Managing values

Sending and receiving value

Value in Solidity is represented by uint128.


On Polkadot, contracts can be compiled with a different type for T::Balance. If you need support for a different type, please raise an issue.

Checking your balance

The balance of a contract can be checked with address .balance, so your own balance is address(this).balance.


Polkadot cannot check the balance for contracts other than the current one. If you need to check the balance of another contract, then add a balance function to that contract like the one below, and call that function instead.


On Solana, checking the balance of an account different than the program account requires that it be passed as an AccountMeta during the transaction. It is not common practice for the program account to hold native Solana tokens.

function balance() public returns (uint128) {
    return address(this).balance;

Creating contracts with an initial value

You can specify the value you want to be deposited in the new contract by specifying {value: 100 ether} before the constructor arguments. This is explained in sending value to the new contract.

Sending value with an external call

You can specify the value you want to be sent along with the function call by specifying {value: 100 ether} before the function arguments. This is explained in passing value and gas with external calls.

Sending value using send() and transfer()

The send() and transfer() functions are available as method on a address payable variable. The single arguments is the amount of value you would like to send. The difference between the two functions is what happens in the failure case: transfer() will revert the current call, send() returns a bool which will be false.

In order for the receiving contract to receive the value, it needs a receive() function, see fallback() and receive() function.

Here is an example:

contract A {
    B other;

    constructor() {
        other = new B();

        bool complete = payable(other).transfer(100);

        if (!complete) {
            // oops

        // if the following fails, our transaction will fail

contract B {
    receive() payable external {
        // ..


On Subtrate, this uses the seal_transfer() mechanism rather than seal_call(), since this does not come with gas overhead. This means the receive() function is not required in the receiving contract, and it will not be called if it is present. If you want the receive() function to be called, use{value: 100}("") instead.


On Solana, send() and transfer() can only transfer native tokens between accounts owned by the contract’s program account, since only the account owner can modify its balance. Use the system instruction library to transfer native tokens between accounts owned by Solana’s system program.