Hi @kHarsh,
A smart contract deployed on the Ethereum blockchain has it’s own Ethereum address and therefore an account balance in ether associated with that address. In this respect it’s no different to an address, and its associated account, used by a person to transact via smart contracts on the same blockchain. Both users and smart contracts are entities that transact with each other.
A smart contract’s initial balance will be zero. This balance will increase when it receives ether from another account address, and decrease when it pays ether to an account address. These other account addresses can be users’ wallet addresses or other smart contracts.
The address that initially deploys a smart contract could either:
- Pay ether into that smart contract on deployment via a constructor marked payable; or
- Pay ether into the smart contract via a payable function, once the contract has already been deployed.
If the value field is set to, say, 50 ether, then in both cases the ether balance associated with the address that deploys the contract or calls the payable function (let’s say the owner address) will reduce by 50 ether, and the contract balance will increase by the same amount. You can see this for yourself by adding either or both of the following pieces of code to a contract and deploying it with the value field set at 50 ether and/or calling the payable function fundContract with the value field set at 50 ether:
address owner;
constructor() payable {
owner = msg.sender;
}
// Allows you to view the current contract balance whenever called
function getContractBalance() public view returns(uint) {
return account(this).balance;
}
AND/OR
// Only include this state variable once if using both pieces of code together
address owner;
// Only include this function once if using both pieces of code together
function getContractBalance() public view returns(uint) {
return account(this).balance;
}
constructor() { // Use the payable constructor if using
owner = msg.sender; // both pieces of code together
}
modifier onlyOwner {
require(msg.sender == owner, "Only the owner can call this function");
_;
}
function fundContract() public payable onlyOwner returns(uint) {
/* we would probably want to add additional functionality here,
but for the purposes of this demonstration it's not necessary. */
}
It is important to note, that a smart contract could still be deployed without an initial ether balance and without receiving any subsequent funding other than the ether paid into the contract by its users. It all depends on what the contract is designed to be used for.
Any ether paid into the contract by its users will be added to the same contract balance as the one increased by funding from the owner address. This is why it is also important to keep track of the separate balances that originate from different addresses in a mapping. This should also be done for any initial or additional funding from the owner — I haven’t included this additional tracking in the code above in order to keep the example simple.