Contract

A Contract object is an abstraction of a contract (EVM bytecode) deployed on the Theta network. It allows for a simple way to serialize calls and transactions to an on-chain contract and deserialize their results and emitted logs.

Define your Contract Address and ABI

const contractAddress = '0x00...00';
const ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"sender\",\"type\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"symbol\",\"type\":\"string\"},{\"name\":\"decimals\",\"type\":\"uint8\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]";

Create Contract

You can pass in a provider (readonly) or a signer (read/write) when creating your contract instance. Behind the scenes, theta.js will parse your ABI and create functions to interact with your contract.

    const provider = new thetajs.providers.HttpProvider(thetajs.networks.ChainIds.Privatenet);
    const contract = new thetajs.Contract(contractAddress, ABI, wallet);

Read-Only Methods (constant)

A constant method is read-only and evaluates a small amount of VM code against the current blockchain state and can be computed by asking a single node, which can return a result. It is therefore free and does not require any TFUEL, but cannot make changes to the blockchain state.

// Read the name of a TNT-20 contract
const name = await contract.name();

Write Methods (non-constant)

A non-constant method requires a transaction to be signed and requires payment in the form of a fee (TFUEL).

// Transaction: Transfer TNT-20 tokens (write)
const result = await contract.transfer("0x000...000", "1000");

Populating a Contract Transaction

You may need to create a SmartContractTransaction object in order to use it for the Theta Wallet Browser Extension to have your user's authorize and sign the transaction. Please see the Theta Web Wallet Browser Extension Developer Guide for more information.

// Transaction: Transfer TNT-20 tokens (write)
const transaction = await contract.populateTransaction.transfer("0x000...000", "1000");

Estimate Gas

You may need to estimate gas for a transaction in order to charge your platform users accordingly, etc.

// Transaction: Transfer TNT-20 tokens (estimate gas)
const estimatedGas = await contract.estimateGas.transfer("0x000...000", "1000");

Overriding variables

You can pass overrides to the transaction by passing an overrides object as the last argument to your contract method to call. You can also include TFUEL (value) when submitting a transaction.

const overrides = {
     gasLimit: 100000, //override the default gasLimit (optional)
     gasPrice: (new BigNumber(0.001)).multipliedBy(Ten18), //override the default gasPrice (optional)
     value: "100000000000000" // tfuelWei to send (optional)
};
const result = await contract.transfer("0x000...000", "1000", overrides);

🚧

Working with overloaded functions

Because the contract injects functions at runtime, you may run into issues with overloaded functions. Here is how to deal with them.

const addFnOverloadedv1 = myContract['add(uint256)'];
const addFnOverloadedv2 = myContract['add(uint256,uint256)'];
const v1Val = await addFnOverloadedv1("1", "2");
const v2Val = await addFnOverloadedv2("1", "2", "3");

What’s Next