Interacting with Contracts

Basic Concepts

To interact with contracts, you need to know a few basic concepts.

The Contract Network

If you aren’t connected to the right network, you aren’t going to have any luck sending transactions to your contract, so make sure you have this right!

Many clever BApps will recognize the user’s current network, and actually adapt to it! For example, if you detect a test network, you could deliberately connect to a test-network version of your smart contract, which makes it easy for users to “try out” your system without using real money!

The Contract Address

Every account in Klaytn has an address, whether it’s an external key-pair account, or a smart contract. In order for any smart contract library to communicate with your contracts, they’ll need to know its exact address.

The Contract ABI

In Klaytn, The ABI Specification is a way to encode the interface of a smart contract in a way that your user interface can make sense of. It is an array of method-describing objects, and when you feed this and the address into a contract-abstraction library like Caver or truffle, this ABI tells those libraries about what methods to provide, and how to compose transactions to call those methods.

The Contract Bytecode

If your web app is going to publish a new smart contract that is pre-compiled, it may need to include some bytecode. In this case, you will not know the contract address in advance, but instead will have to publish, watch for the transaction to be processed, and then extract the final contract’s address from the completed transaction.

If publishing a contract from bytecode, you will still want an ABI if you want to interact with it! The bytecode does not describe how to interact with the final contract.

The Contract Source Code

If your website is going to allow users to edit smart contract source code and compile it, like Klaytn IDE, you may import a whole compiler, in which case you’re going to derive your bytecode and ABI from that source code, and eventually you will derive the contract’s address from the completed transaction publishing that bytecode.

Examples

Smart Contract Deployment

Before deployment, you need to prepare contract's bytecode and ABI. You can either use Truffle framework or Klaytn IDE to easily get them.

const caver = new Caver(klaytn)

caver.klay.sendTransaction({
  type: 'SMART_CONTRACT_DEPLOY',
  data: '0x608060405260006008553480156...' //compiled bytecode
  from: klaytn.selectedAddress,
  to: '0x0000000000000000000000000000000000000000',
  value: caver.utils.toPeb('1', 'KLAY'),
  gas: 8000000,
})
.once('transactionHash', transactionHash => {
  console.log('txHash', transactionHash)
})
.once('receipt', receipt => {
  console.log('receipt', receipt)
})
.once('error', error => {
  console.log('error', error)
})

You can also use caver.klay.Contract object.

const caver = new Caver(klaytn)

const myContract = new caver.klay.Contract(contractABI)

myContract.deploy({
    data: '0x12345...',
    arguments: [123, 'My String']
  })
  .send({
    from: klaytn.selectedAddress,
    gas: 1500000,
    value: 0,
  }, function(error, transactionHash) { ... })
  .on('error', function(error) { ... })
  .on('transactionHash', function(transactionHash) { ... })
  .on('receipt', function(receipt) {
    console.log(receipt.contractAddress) // contains the new contract address
   })
  .then(function(newContractInstance) {
    console.log(newContractInstance.options.address) // instance with the new contract address
  });

Calling Contract's Methods

function transfer(address recipient, uint256 amount) public returns (bool) Let's assume that we are calling token transfer function above. There are two different ways to call this contract method.

const caver = new Caver(klaytn)
const data = caver.klay.abi.encodeFunctionCall(
  {
    name: 'transfer',
    type: 'function',
    inputs: [
      {
        type: 'address',
        name: 'recipient'
      },
      {
        type: 'uint256',
        name: 'amount'
      }
    ]
  },
  [to, caver.utils.toPeb(amount, 'KLAY')]
)

caver.klay.sendTransaction({
  type: 'SMART_CONTRACT_EXECUTION',
  from: klaytn.selectedAddress,
  to: contractAddress,
  gas: '8000000',
  data
})

You can also use caver.klay.Contract object here too.

const caver = new Caver(klaytn)

const myContract = new caver.klay.Contract(contractABI, contractAddress)

myContract.methods.transfer(
  to, caver.utils.toPeb(amount, 'KLAY')
).send({from: klaytn.selectedAddress},
  function(error, transactionHash) {
    ...
  });

When triggered, the following pop-up will be shown, asking for the user's confirmation.

If you want to know more about caver.klay.Contract object, please refer to here.

Last updated