Hedera
Search…
Deploy a Contract Using the Hedera Token Service

Summary

In this example, you will learn how to create a Solidity contract that interacts with the Hedera Token Service (HTS). The initial release of this feature supports token mint, burn, associate, dissociate, and transfer transactions.
The example does not cover the environment set-up or creating certain variables that may be seen in the code blocks. The full coding example can be found at the end of the page.
Smart contract entity auto renewal and expiry will be enabled in a future release. Please check out HIP-16 for more information.

1. Create Your "HTS" Smart Contract

In this example, you will associate a token to an account and transfer tokens to the associated account by interacting with the HTS contract deployed to Hedera. The "HTS" contract has three functions that allow you to associate, transfer, and dissociate tokens from a Hedera account.
  • tokenAssociate
  • tokenTransfer
  • tokenDissociate
The HTS.sol will serve as a reference to the contract that was compiled. The HTS.json file contains the data.bytecode.object field that will be used to store the contract bytecode in a file on the Hedera network.
To write a contract using HTS, you will need to add the HTS Solidity support libraries to your project and import them into your contract. Please see the HTS.sol example for reference. The IHederaTokenService.sol will need to be in the same directory as the other two files. An explanation of the functions can be found here.
HTS.sol
HTS.json
1
// SPDX-License-Identifier: Apache-2.0
2
pragma solidity ^0.6.12;
3
​
4
import "./HederaTokenService.sol";
5
import "./HederaResponseCodes.sol";
6
​
7
​
8
contract HTS is HederaTokenService {
9
​
10
function tokenAssociate(address sender, address tokenAddress) external {
11
int response = HederaTokenService.associateToken(sender, tokenAddress);
12
​
13
if (response != HederaResponseCodes.SUCCESS) {
14
revert ("Associate Failed");
15
}
16
}
17
​
18
function tokenTransfer(address tokenId, address fromAccountId , address toAccountId , int64 tokenAmount) external {
19
int response = HederaTokenService.transferToken(tokenId, fromAccountId, toAccountId, tokenAmount);
20
​
21
if (response != HederaResponseCodes.SUCCESS) {
22
revert ("Transfer Failed");
23
}
24
}
25
​
26
function tokenDissociate(address sender, address tokenAddress) external {
27
int response = HederaTokenService.dissociateToken(sender, tokenAddress);
28
​
29
if (response != HederaResponseCodes.SUCCESS) {
30
revert ("Dissociate Failed");
31
}
32
}
33
}
Copied!
1
{
2
"deploy": {
3
"VM:-": {
4
"linkReferences": {},
5
"autoDeployLib": true
6
},
7
"main:1": {
8
"linkReferences": {},
9
"autoDeployLib": true
10
},
11
"ropsten:3": {
12
"linkReferences": {},
13
"autoDeployLib": true
14
},
15
"rinkeby:4": {
16
"linkReferences": {},
17
"autoDeployLib": true
18
},
19
"kovan:42": {
20
"linkReferences": {},
21
"autoDeployLib": true
22
},
23
"gΓΆrli:5": {
24
"linkReferences": {},
25
"autoDeployLib": true
26
},
27
"Custom": {
28
"linkReferences": {},
29
"autoDeployLib": true
30
}
31
},
32
"data": {
33
"bytecode": {
34
"linkReferences": {},
35
"object": "608060405234801561001057600080fd5b5061089d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80633a04033c146100465780634753b51b146100d75780637f6314d01461013b575b600080fd5b6100d56004803603608081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560070b906020019092919050505061019f565b005b610139600480360360408110156100ed57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061022f565b005b61019d6004803603604081101561015157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102bb565b005b60006101ad85858585610347565b9050601660030b8114610228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5472616e73666572204661696c6564000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600061023b8383610519565b9050601660030b81146102b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f446973736f6369617465204661696c656400000000000000000000000000000081525060200191505060405180910390fd5b505050565b60006102c783836106c0565b9050601660030b8114610342576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4173736f6369617465204661696c65640000000000000000000000000000000081525060200191505060405180910390fd5b505050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff1663eca3691760e01b88888888604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018260070b8152602001945050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061046b5780518252602082019150602081019050602083039250610448565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146104cd576040519150601f19603f3d011682016040523d82523d6000602084013e6104d2565b606091505b5091509150816104e357601561050a565b8080602001905160208110156104f857600080fd5b81019080805190602001909291905050505b60030b92505050949350505050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff1663099794e860e01b8686604051602401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061061457805182526020820191506020810190506020830392506105f1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610676576040519150601f19603f3d011682016040523d82523d6000602084013e61067b565b606091505b50915091508161068c5760156106b3565b8080602001905160208110156106a157600080fd5b81019080805190602001909291905050505b60030b9250505092915050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff166349146bde60e01b8686604051602401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106107bb5780518252602082019150602081019050602083039250610798565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461081d576040519150601f19603f3d011682016040523d82523d6000602084013e610822565b606091505b50915091508161083357601561085a565b80806020019051602081101561084857600080fd5b81019080805190602001909291905050505b60030b925050509291505056fea264697066735822122068ba1095e27dfaf338e8ee9d0914f328fe6a23627ce5b8245b5fd09275ba76d964736f6c634300060c0033",
36
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x89D DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x3A04033C EQ PUSH2 0x46 JUMPI DUP1 PUSH4 0x4753B51B EQ PUSH2 0xD7 JUMPI DUP1 PUSH4 0x7F6314D0 EQ PUSH2 0x13B JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD5 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x80 DUP2 LT ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH1 0x7 SIGNEXTEND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x19F JUMP JUMPDEST STOP JUMPDEST PUSH2 0x139 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0xED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x22F JUMP JUMPDEST STOP JUMPDEST PUSH2 0x19D PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x151 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x2BB JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 PUSH2 0x1AD DUP6 DUP6 DUP6 DUP6 PUSH2 0x347 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x228 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0xF DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x5472616E73666572204661696C65640000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x23B DUP4 DUP4 PUSH2 0x519 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x2B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x446973736F6369617465204661696C6564000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C7 DUP4 DUP4 PUSH2 0x6C0 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x342 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x10 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x4173736F6369617465204661696C656400000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xECA36917 PUSH1 0xE0 SHL DUP9 DUP9 DUP9 DUP9 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x7 SIGNEXTEND DUP2 MSTORE PUSH1 0x20 ADD SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x46B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x448 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x4CD JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x4D2 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x4E3 JUMPI PUSH1 0x15 PUSH2 0x50A JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x4F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x99794E8 PUSH1 0xE0 SHL DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x614 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x5F1 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x676 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x67B JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x68C JUMPI PUSH1 0x15 PUSH2 0x6B3 JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x6A1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x49146BDE PUSH1 0xE0 SHL DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x7BB JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x798 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x81D JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x822 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x833 JUMPI PUSH1 0x15 PUSH2 0x85A JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x848 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH9 0xBA1095E27DFAF338E8 0xEE SWAP14 MULMOD EQ RETURN 0x28 INVALID PUSH11 0x23627CE5B8245B5FD09275 0xBA PUSH23 0xD964736F6C634300060C00330000000000000000000000 ",
37
"sourceMap": "138:923:0:-:0;;;;;;;;;;;;;;;;;;;"
38
},
39
"deployedBytecode": {
40
"immutableReferences": {},
41
"linkReferences": {},
42
"object": "608060405234801561001057600080fd5b50600436106100415760003560e01c80633a04033c146100465780634753b51b146100d75780637f6314d01461013b575b600080fd5b6100d56004803603608081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560070b906020019092919050505061019f565b005b610139600480360360408110156100ed57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061022f565b005b61019d6004803603604081101561015157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102bb565b005b60006101ad85858585610347565b9050601660030b8114610228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f5472616e73666572204661696c6564000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600061023b8383610519565b9050601660030b81146102b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f446973736f6369617465204661696c656400000000000000000000000000000081525060200191505060405180910390fd5b505050565b60006102c783836106c0565b9050601660030b8114610342576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4173736f6369617465204661696c65640000000000000000000000000000000081525060200191505060405180910390fd5b505050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff1663eca3691760e01b88888888604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018260070b8152602001945050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061046b5780518252602082019150602081019050602083039250610448565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146104cd576040519150601f19603f3d011682016040523d82523d6000602084013e6104d2565b606091505b5091509150816104e357601561050a565b8080602001905160208110156104f857600080fd5b81019080805190602001909291905050505b60030b92505050949350505050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff1663099794e860e01b8686604051602401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061061457805182526020820191506020810190506020830392506105f1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610676576040519150601f19603f3d011682016040523d82523d6000602084013e61067b565b606091505b50915091508161068c5760156106b3565b8080602001905160208110156106a157600080fd5b81019080805190602001909291905050505b60030b9250505092915050565b600080606061016773ffffffffffffffffffffffffffffffffffffffff166349146bde60e01b8686604051602401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106107bb5780518252602082019150602081019050602083039250610798565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461081d576040519150601f19603f3d011682016040523d82523d6000602084013e610822565b606091505b50915091508161083357601561085a565b80806020019051602081101561084857600080fd5b81019080805190602001909291905050505b60030b925050509291505056fea264697066735822122068ba1095e27dfaf338e8ee9d0914f328fe6a23627ce5b8245b5fd09275ba76d964736f6c634300060c0033",
43
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x3A04033C EQ PUSH2 0x46 JUMPI DUP1 PUSH4 0x4753B51B EQ PUSH2 0xD7 JUMPI DUP1 PUSH4 0x7F6314D0 EQ PUSH2 0x13B JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD5 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x80 DUP2 LT ISZERO PUSH2 0x5C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH1 0x7 SIGNEXTEND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x19F JUMP JUMPDEST STOP JUMPDEST PUSH2 0x139 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0xED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x22F JUMP JUMPDEST STOP JUMPDEST PUSH2 0x19D PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x151 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x2BB JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 PUSH2 0x1AD DUP6 DUP6 DUP6 DUP6 PUSH2 0x347 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x228 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0xF DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x5472616E73666572204661696C65640000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x23B DUP4 DUP4 PUSH2 0x519 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x2B6 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x11 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x446973736F6369617465204661696C6564000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2C7 DUP4 DUP4 PUSH2 0x6C0 JUMP JUMPDEST SWAP1 POP PUSH1 0x16 PUSH1 0x3 SIGNEXTEND DUP2 EQ PUSH2 0x342 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x10 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x4173736F6369617465204661696C656400000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0xECA36917 PUSH1 0xE0 SHL DUP9 DUP9 DUP9 DUP9 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH1 0x7 SIGNEXTEND DUP2 MSTORE PUSH1 0x20 ADD SWAP5 POP POP POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x46B JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x448 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x4CD JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x4D2 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x4E3 JUMPI PUSH1 0x15 PUSH2 0x50A JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x4F8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x99794E8 PUSH1 0xE0 SHL DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x614 JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x5F1 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x676 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x67B JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x68C JUMPI PUSH1 0x15 PUSH2 0x6B3 JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x6A1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x60 PUSH2 0x167 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH4 0x49146BDE PUSH1 0xE0 SHL DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x24 ADD DUP1 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP3 POP POP POP PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE SWAP1 PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF NOT AND PUSH1 0x20 DUP3 ADD DUP1 MLOAD PUSH28 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP4 DUP2 DUP4 AND OR DUP4 MSTORE POP POP POP POP PUSH1 0x40 MLOAD DUP1 DUP3 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 JUMPDEST PUSH1 0x20 DUP4 LT PUSH2 0x7BB JUMPI DUP1 MLOAD DUP3 MSTORE PUSH1 0x20 DUP3 ADD SWAP2 POP PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH1 0x20 DUP4 SUB SWAP3 POP PUSH2 0x798 JUMP JUMPDEST PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB DUP1 NOT DUP3 MLOAD AND DUP2 DUP5 MLOAD AND DUP1 DUP3 OR DUP6 MSTORE POP POP POP POP POP POP SWAP1 POP ADD SWAP2 POP POP PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP7 GAS CALL SWAP2 POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x81D JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x822 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP2 POP SWAP2 POP DUP2 PUSH2 0x833 JUMPI PUSH1 0x15 PUSH2 0x85A JUMP JUMPDEST DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x848 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP JUMPDEST PUSH1 0x3 SIGNEXTEND SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH9 0xBA1095E27DFAF338E8 0xEE SWAP14 MULMOD EQ RETURN 0x28 INVALID PUSH11 0x23627CE5B8245B5FD09275 0xBA PUSH23 0xD964736F6C634300060C00330000000000000000000000 ",
44
"sourceMap": "138:923:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;451:334;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;791:268;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;180:265;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;451:334;575:12;590:82;623:7;632:13;647:11;660;590:32;:82::i;:::-;575:97;;2733:2:1;687:39:0;;:8;:39;683:96;;742:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;683:96;451:334;;;;;:::o;791:268::-;873:12;888:56;923:6;931:12;888:34;:56::i;:::-;873:71;;2733:2:1;959:39:0;;:8;:39;955:98;;1014:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;955:98;791:268;;;:::o;180:265::-;261:12;276:55;310:6;318:12;276:33;:55::i;:::-;261:70;;2733:2:1;346:39:0;;:8;:39;342:97;;401:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;342:97;180:265;;;:::o;10522:429:2:-;10634:16;10667:12;10681:19;291:5;10704:22;;10763:42;;;10819:5;10826:6;10834:8;10844:6;10740:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10704:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10666:186;;;;10877:7;:67;;2587:2:1;10877:67:2;;;10898:6;10887:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10877:67;10862:82;;;;10522:429;;;;;;;;:::o;8041:373::-;8116:16;8145:12;8159:19;291:5;8182:22;;8241:44;;;8299:7;8308:5;8218:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8182:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8144:171;;;;8340:7;:67;;2587:2:1;8340:67:2;;;8361:6;8350:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8340:67;8325:82;;;;8041:373;;;;;;:::o;5734:371::-;5808:16;5837:12;5851:19;291:5;5874:22;;5933:43;;;5990:7;5999:5;5910:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5874:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5836:170;;;;6031:7;:67;;2587:2:1;6031:67:2;;;6052:6;6041:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6031:67;6016:82;;;;5734:371;;;;;;:::o"
45
},
46
"gasEstimates": {
47
"creation": {
48
"codeDepositCost": "441000",
49
"executionCost": "474",
50
"totalCost": "441474"
51
},
52
"external": {
53
"tokenAssociate(address,address)": "infinite",
54
"tokenDissociate(address,address)": "infinite",
55
"tokenTransfer(address,address,address,int64)": "infinite"
56
}
57
},
58
"methodIdentifiers": {
59
"tokenAssociate(address,address)": "7f6314d0",
60
"tokenDissociate(address,address)": "4753b51b",
61
"tokenTransfer(address,address,address,int64)": "3a04033c"
62
}
63
},
64
"abi": [
65
{
66
"inputs": [
67
{
68
"internalType": "address",
69
"name": "sender",
70
"type": "address"
71
},
72
{
73
"internalType": "address",
74
"name": "tokenAddress",
75
"type": "address"
76
}
77
],
78
"name": "tokenAssociate",
79
"outputs": [],
80
"stateMutability": "nonpayable",
81
"type": "function"
82
},
83
{
84
"inputs": [
85
{
86
"internalType": "address",
87
"name": "sender",
88
"type": "address"
89
},
90
{
91
"internalType": "address",
92
"name": "tokenAddress",
93
"type": "address"
94
}
95
],
96
"name": "tokenDissociate",
97
"outputs": [],
98
"stateMutability": "nonpayable",
99
"type": "function"
100
},
101
{
102
"inputs": [
103
{
104
"internalType": "address",
105
"name": "tokenId",
106
"type": "address"
107
},
108
{
109
"internalType": "address",
110
"name": "fromAccountId",
111
"type": "address"
112
},
113
{
114
"internalType": "address",
115
"name": "toAccountId",
116
"type": "address"
117
},
118
{
119
"internalType": "int64",
120
"name": "tokenAmount",
121
"type": "int64"
122
}
123
],
124
"name": "tokenTransfer",
125
"outputs": [],
126
"stateMutability": "nonpayable",
127
"type": "function"
128
}
129
]
130
}
Copied!

2. Store the Smart Contract Bytecode on Hedera

Create a file using the FileCreateTransaction() API to store the hex-encoded byte code of the "HTS" contract. Once the file is created you can obtain the file ID from the receipt of the transaction.
Note: The bytecode is required to be hex-encoded. It should not be the actual data the hex represents.
Java
JavaScript
Go
1
//Import the HTS.json file from the resources folder
2
ClassLoader cl = HTS.class.getClassLoader();
3
​
4
Gson gson = new Gson();
5
JsonObject jsonObject;
6
​
7
//Get the json file
8
InputStream jsonStream = cl.getResourceAsStream("HTS.json");
9
jsonObject = gson.fromJson(new InputStreamReader(jsonStream, StandardCharsets.UTF_8), JsonObject.class);
10
​
11
​
12
//Store the "object" field from the HTS.json file as hex-encoded bytecode
13
String object = jsonObject.getAsJsonObject("data").getAsJsonObject("bytecode").get("object").getAsString();
14
byte[] bytecode = object.getBytes(StandardCharsets.UTF_8);
15
​
16
//Create a file on Hedera and store the hex-encoded bytecode
17
FileCreateTransaction fileCreateTx = new FileCreateTransaction()
18
.setKeys(privateKeyTest)
19
.setContents(bytecode);
20
​
21
//Submit the file to the Hedera test network
22
TransactionResponse submitTx = fileCreateTx.execute(client);
23
​
24
//Get the receipt of the file create transaction
25
TransactionReceipt fileReceipt = submitTx.getReceipt(client);
26
​
27
//Get the file ID
28
FileId newFileId = fileReceipt.fileId;
29
​
30
//Log the file ID
31
System.out.println("The smart contract byte code file ID is " + newFileId);
32
​
33
//v2.6.0 Hedera Java SDK
Copied!
1
//Get the contract bytecode
2
const bytecode = htsContract.data.bytecode.object;
3
​
4
//Create a file on Hedera and store the hex-encoded bytecode
5
const fileCreateTx = new FileCreateTransaction()
6
.setContents(bytecode);
7
​
8
//Submit the file to the Hedera test network signing with the transaction fee payer key specified with the client
9
const submitTx = await fileCreateTx.execute(client);
10
​
11
//Get the receipt of the file create transaction
12
const fileReceipt = await submitTx.getReceipt(client);
13
​
14
//Get the file ID from the receipt
15
const bytecodeFileId = fileReceipt.fileId;
16
​
17
//Log the file ID
18
console.log("The smart contract bytecode file ID is " +bytecodeFileId)
Copied!
1
//Get the HTS contract bytecode
2
rawSmartContract, err := ioutil.ReadFile("./hts.json")
3
if err != nil {
4
println(err.Error(), ": error reading hts.json")
5
return
6
}
7
​
8
var contract contract = contract{}
9
​
10
err = json.Unmarshal([]byte(rawSmartContract), &contract)
11
if err != nil {
12
println(err.Error(), ": error unmarshaling the json file")
13
return
14
}
15
​
16
smartContractByteCode := []byte(contract.Object)
17
​
18
// Upload a file containing the byte code
19
fileCreateTx, err := hedera.NewFileCreateTransaction().
20
SetContents([]byte(smartContractByteCode)).
21
Execute(client)
22
​
23
if err != nil {
24
println(err.Error(), ": error creating file")
25
return
26
}
27
​
28
//Get the receipt of the transaction
29
fileTxReceipt, err := fileCreateTx.GetReceipt(client)
30
if err != nil {
31
println(err.Error(), ": error getting file create transaction receipt")
32
return
33
}
34
​
35
//Get the bytecode file ID
36
byteCodeFileID := *fileTxReceipt.FileID
37
​
38
fmt.Printf("The contract bytecode file ID: %v\n", byteCodeFileID)
Copied!

3. Deploy a Hedera Smart Contract

Create the contract and set the file ID to the file that contains the hex-encoded bytecode from the previous step. You will need to set the gas high enough to deploy the contract. The gas should be estimated to be within 25% of the actual gas cost to avoid paying extra gas. You can read more about gas and fees here.
You will need to set the gas value high enough to deploy the contract. If you don't have enough gas you will receive an INSUFFICIENT_GAS response. If you set the value too high you will be refunded a maximum of 20% of the amount that was set for the transaction.\
Java
JavaScript
Go
1
//Deploy the contract
2
ContractCreateTransaction contractTx = new ContractCreateTransaction()
3
//The contract bytecode file
4
.setBytecodeFileId(newFileId)
5
//The max gas to reserve for this transaction
6
.setGas(2_000_000);
7
​
8
//Submit the transaction to the Hedera test network
9
TransactionResponse contractResponse = contractTx.execute(client);
10
​
11
//Get the receipt of the file create transaction
12
TransactionReceipt contractReceipt = contractResponse.getReceipt(client);
13
​
14
//Get the smart contract ID
15
ContractId newContractId = contractReceipt.contractId;
16
​
17
//Log the smart contract ID
18
System.out.println("The smart contract ID is " + newContractId);
19
​
20
//v2.6.0 Hedera Java SDK
Copied!
1
//Deploy the contract instance
2
const contractTx = await new ContractCreateTransaction()
3
//The bytecode file ID
4
.setBytecodeFileId(bytecodeFileId)
5
//The max gas to reserve
6
.setGas(2000000);
7
​
8
//Submit the transaction to the Hedera test network
9
const contractResponse = await contractTx.execute(client);
10
​
11
//Get the receipt of the file create transaction
12
const contractReceipt = await contractResponse.getReceipt(client);
13
​
14
//Get the smart contract ID
15
const newContractId = contractReceipt.contractId;
16
​
17
//Log the smart contract ID
18
console.log("The smart contract ID is " + newContractId);
Copied!
1
// Deploy the contract instance
2
contractTransactionID, err := hedera.NewContractCreateTransaction().
3
//The max gas for the transaction
4
SetGas(2000000).
5
//The contract bytecode file ID
6
SetBytecodeFileID(byteCodeFileID).
7
Execute(client)
8
​
9
if err != nil {
10
println(err.Error(), ": error creating contract")
11
return
12
}
13
​
14
//Get the contract receipt
15
contractReceipt, err := contractTransactionID.GetReceipt(client)
16
​
17
//Get the contract contract ID
18
contractId := *contractReceipt.ContractID
19
​
20
//Log the contract ID
21
fmt.Printf("The contract ID %v\n", contractId)
Copied!

4. Call the tokenAssociate Contract Function

The tokenAssociate function in the contract will associate a token that was created using the native Hedera Token Service. You can create a new token using HTS or using an existing token in this example. Use the ContractExecuteTransaction() API to call the contract's tokenAssociate function. You will pass the token ID and account ID in Solidity address format to the contract function. The contract function parameters need to be provided in the order expected by the function to successfully execute.
Java
JavaScript
Go
1
//Associate the token to an account using the HTS contract
2
ContractExecuteTransaction associateToken = new ContractExecuteTransaction()
3
//The contract to call
4
.setContractId(newContractId)
5
//The gas for the transaction
6
.setGas(2_000_000)
7
//The contract function to call and parameters to pass
8
.setFunction("tokenAssociate", new ContractFunctionParameters()
9
//The account ID to associate the token to
10
.addAddress(accountIdTest.toSolidityAddress())
11
//The token ID to associate to the account
12
.addAddress(tokenId.toSolidityAddress()));
13
​
14
//Sign with the account key to associate and submit to the Hedera network
15
TransactionResponse associateTokenResponse = associateToken.freezeWith(client).sign(privateKeyTest).execute(client);
16
​
17
System.out.println("The transaction status: " +associateTokenResponse.getReceipt(client).status);
Copied!
1
//Associate the token to an account using the HTS contract
2
const associateToken = new ContractExecuteTransaction()
3
//The contract to call
4
.setContractId(newContractId)
5
//The gas for the transaction
6
.setGas(2000000)
7
//The contract function to call and parameters to pass
8
.setFunction("tokenAssociate", new ContractFunctionParameters()
9
//The account ID to associate the token to
10
.addAddress(accountIdTest.toSolidityAddress())
11
//The token ID to associate to the account
12
.addAddress(tokenId.toSolidityAddress()));
13
​
14
//Sign with the account key and submit to the Hedera network
15
const signTx = await associateToken.freezeWith(client).sign(accountKeyTest);
16
17
//Submit the transaction
18
const submitAssociateTx = await signTx.execute(client);
19
​
20
//Get the receipt
21
const txReceipt = await submitAssociateTx.getReceipt(client);
22
​
23
//Get transaction status
24
const txStatus = txReceipt.status
25
​
26
console.log("The associate transaction was " + txStatus.toString())
Copied!
1
//Construct a Solidity address from token ID
2
tokenIdToSol := tokenId.ToSolidityAddress()
3
​
4
//Construct a Solidity address from account ID
5
accountIdToSol := accountIdTest.ToSolidityAddress()
6
​
7
//Add the function parameters in order for tokenAssociate
8
contractParamsAccount, err := hedera.NewContractFunctionParameters().AddAddress(accountIdToSol)
9
​
10
contractParamsToken, err := contractParamsAccount.AddAddress(tokenIdToSol)
11
​
12
//Associate an account with a token
13
associateTx, err := hedera.NewContractExecuteTransaction().
14
//The contract ID
15
SetContractID(contractId).
16
//The max gas
17
SetGas(2000000).
18
//The contract function to call and parameters
19
SetFunction("tokenAssociate", contractParamsToken).
20
Execute(client)
21
​
22
if err != nil {
23
println(err.Error(), ": error executing contract")
24
return
25
}
26
​
27
//Get the receipt
28
associateTxReceipt, err := associateTx.GetReceipt(client)
29
​
30
//Get transaction status
31
txStatus := associateTxReceipt.Status
32
​
33
fmt.Printf("The associate transaction status %v\n", txStatus)
Copied!

5. Get the tokenAssociate Transaction Record

The contract execute transaction that triggered a subsequent token associate transaction in the contract is an example of a nested transaction. The contract execute transaction is the parent transaction and the token associate transaction is referred to as the child transaction. Both parent and child transactions share the same payer account ID and transaction valid duration with the exception of the child transaction having a nonce value at the end. The nonce value increments for each subsequent child transaction.
  • Parent Transaction ID: 0.0.2252@1640119571.329880313
  • Child Transaction ID: 0.0.2252@1640119571.329880313/1
The parent transaction record, receipt, or response will only return the parent transaction information. If you would like to get the child transaction record, receipt, or response you will need to use the TransactionRecordQuery() or TransactionReceiptQuery() and set children equal to true. The child transaction record will also have a parentConsensusTimestamp field populated with the consensus timestamp of the parent transaction.
To confirm the account was associated with the token, request the balance of the account. The account balance should show the ID of the token that was associated with a zero balance.
Java
JavaScript
Go
1
//Get the child token associate transaction record
2
TransactionRecord childRecords = new TransactionRecordQuery()
3
//Set the bool flag equal to true
4
.setIncludeChildren(true)
5
//The transaction ID of th parent contract execute transaction
6
.setTransactionId(associateTokenResponse.transactionId)
7
.execute(client);
8
​
9
System.out.println("The transaction record for the associate transaction" +childRecords.children.get(0));
10
​
11
//The balance of the account
12
AccountBalance accountBalance3 = new AccountBalanceQuery()
13
.setAccountId(accountIdTest)
14
.execute(client);
15
​
16
System.out.println("The " + tokenId + " should now be associated to my account: " + accountBalance3.tokens);
Copied!
1
//Get the token associate transaction record
2
const childRecords = new TransactionRecordQuery()
3
//Set children equal to true for child records
4
.setIncludeChildren(true)
5
//The parent transaction ID
6
.setTransactionId(submitAssociateTx.transactionId)
7
.setQueryPayment(new Hbar(10))
8
.execute(client);
9
10
​
11
console.log("The transaction record for the associate transaction" +JSON.stringify((await childRecords).children));
12
​
13
//The balance of the account
14
const accountBalance = new AccountBalanceQuery()
15
.setAccountId(accountIdTest)
16
.execute(client);
17
​
18
console.log("The " + tokenId + " should now be associated to my account: " + (await accountBalance).tokens.toString());
Copied!
1
//Get the child transaction record
2
childRecord, err := hedera.NewTransactionRecordQuery().
3
//Set boolean equal to true
4
SetIncludeChildren(true).
5
//Parent transaction ID
6
SetTransactionID(associateTx.TransactionID).
7
Execute(client)
8
​
9
if err != nil {
10
println(err.Error(), ": error getting record")
11
return
12
}
13
​
14
//Log the child record
15
fmt.Printf("The associate child transaction record %v\n", childRecord.Children)
16
​
17
//The balance of the account
18
accountBalance, err := hedera.NewAccountBalanceQuery().
19
SetAccountID(accountIdTest).
20
Execute(client)
21
​
22
if err != nil {
23
println(err.Error(), ": error getting balance")
24
return
25
}
26
​
27
fmt.Printf("The account token balance %v\n", accountBalance.Tokens)
Copied!

6. Call the tokenTransfer Contract Function

Transfer 100 units of the token to the account that was associated with the token. You will use the ContractExecuteTransaction() API and set the contract function to tokenTransfer. The contract function parameters must be provided in the order of the function expects to receive them.
The transaction must be signed by the account that is sending the tokens. In this case, it is the treasury account.
You can verify the transfer was successful by checking the account token balance!
Java
JavaScript
Go
1
//Transfer the new token to the account
2
//Contract function params need to be in the order of the paramters provided in the tokenTransfer contract function
3
ContractExecuteTransaction tokenTransfer = new ContractExecuteTransaction()
4
.setContractId(newContractId)
5
.setGas(2_000_000)
6
.setFunction("tokenTransfer", new ContractFunctionParameters()
7
//The ID of the token
8
.addAddress(tokenId.toSolidityAddress())
9
//The account to transfer the tokens from
10
.addAddress(treasuryAccountId.toSolidityAddress())
11
//The account to transfer the tokens to
12
.addAddress(accountIdTest.toSolidityAddress())
13
//The number of tokens to transfer
14
.addInt64(100));
15
​
16
//Sign the token transfer transaction with the treasury account to authorize the transfer and submit
17
ContractExecuteTransaction signTokenTransfer = tokenTransfer.freezeWith(client).sign(treasuryKey);
18
​
19
//Submit transfer transaction
20
TransactionResponse submitTransfer = signTokenTransfer.execute(client);
21
​
22
//Get transaction status
23
Status txStatus = submitTransfer.getReceipt(client).status;
24
​
25
//Verify your account received the 100 tokens
26
AccountBalance newAccountBalance = new AccountBalanceQuery()
27
.setAccountId(accountIdTest)
28
.execute(client);
29
​
30
System.out.println("My new account balance is " +newAccountBalance.tokens);
Copied!
1
//Transfer the new token to the account
2
//Contract function params need to be in the order of the paramters provided in the tokenTransfer contract function
3
const tokenTransfer = new ContractExecuteTransaction()
4
.setContractId(newContractId)
5
.setGas(2000000)
6
.setFunction("tokenTransfer", new ContractFunctionParameters()
7
//The ID of the token
8
.addAddress(tokenId.toSolidityAddress())
9
//The account to transfer the tokens from
10
.addAddress(treasuryAccountId.toSolidityAddress())
11
//The account to transfer the tokens to
12
.addAddress(accountIdTest.toSolidityAddress())
13
//The number of tokens to transfer
14
.addInt64(100));
15
​
16
//Sign the token transfer transaction with the treasury account to authorize the transfer and submit
17
const signTokenTransfer = await tokenTransfer.freezeWith(client).sign(treasuryKey);
18
​
19
//Submit transfer transaction
20
const submitTransfer = await signTokenTransfer.execute(client);
21
​
22
//Get transaction status
23
const transferTxStatus = await (await submitTransfer.getReceipt(client)).status;
24
​
25
//Get the transaction status
26
console.log("The transfer transaction status " +transferTxStatus.toString());
27
​
28
//Verify the account received the 100 tokens
29
const newAccountBalance = new AccountBalanceQuery()
30
.setAccountId(accountIdTest)
31
.execute(client);
32
33
console.log("My new account balance is " +(await newAccountBalance).tokens.toString());
Copied!
1
//Transfer the token
2
transferTx := hedera.NewContractExecuteTransaction().
3
//The contract ID
4
SetContractID(contractId).
5
//The max gas
6
SetGas(2000000).
7
//The contract function to call and parameters
8
SetFunction("tokenTransfer", contractParamsAmount)
9
​
10
//Sign with treasury key to authorize the transfer from the treasury account
11
signTx, err := transferTx.Sign(treasuryKey).Execute(client)
12
​
13
if err != nil {
14
println(err.Error(), ": error executing contract")
15
return
16
}
17
//Get the receipt
18
transferTxReceipt, err := signTx.GetReceipt(client)
19
​
20
if err != nil {
21
println(err.Error(), ": error getting receipt")
22
return
23
}
24
​
25
//Get transaction status
26
transferTxStatus := transferTxReceipt.Status
27
​
28
fmt.Printf("The transfer transaction status %v\n", transferTxStatus)
29
​
30
//Verify the transfer by checking the balance
31
transferAccountBalance, err := hedera.NewAccountBalanceQuery().
32
SetAccountID(accountIdTest).
33
Execute(client)
34
​
35
if err != nil {
36
println(err.Error(), ": error getting balance")
37
return
38
}
39
​
40
//Log the account token balance
41
fmt.Printf("The account token balance %v\n", transferAccountBalance.Tokens)
Copied!
Check out our smart contract mirror node rest APIs that return information about a contract like contract results and logs!

Congratulations
πŸŽ‰
! You have completed the following:

  • Created a smart contract that calls HTS transactions
  • Associated a HTS token by using the deployed contract
  • Requested a transaction record for a nested transaction
  • Transferred tokens using the deployed contract

Code Check βœ…

Java
JavaScript
Go
1
import com.google.gson.Gson;
2
import com.google.gson.JsonObject;
3
import com.hedera.hashgraph.sdk.*;
4
​
5
import io.github.cdimascio.dotenv.Dotenv;
6
import java.io.IOException;
7
import java.io.InputStream;
8
import java.io.InputStreamReader;
9
import java.nio.charset.StandardCharsets;
10
import java.util.concurrent.TimeoutException;
11
​
12
​
13
public class HTS {
14
​
15
public static void main(String[] args) throws TimeoutException, PrecheckStatusException, ReceiptStatusException, InterruptedException, IOException {
16
​
17
AccountId accountIdTest = AccountId.fromString(Dotenv.load().get("PREVIEWNET_ACCOUNT_ID"));
18
PrivateKey privateKeyTest = PrivateKey.fromString(Dotenv.load().get("PREVIEWNET_PRIVATE_KEY"));
19
​
20
Client client = Client.forPreviewnet();
21
client.setOperator(accountIdTest, privateKeyTest);
22
​
23
//Import the HTS.json file from the resources folder
24
ClassLoader cl = HTS.class.getClassLoader();
25
​
26
Gson gson = new Gson();
27
JsonObject jsonObject;
28
​
29
//Get the json file
30
InputStream jsonStream = cl.getResourceAsStream("HTS.json");
31
jsonObject = gson.fromJson(new InputStreamReader(jsonStream, StandardCharsets.UTF_8), JsonObject.class);
32
​
33
​
34
//Store the "object" field from the HTS.json file as hex-encoded bytecode
35
String object = jsonObject.getAsJsonObject("data").getAsJsonObject("bytecode").get("object").getAsString();
36
byte[] bytecode = object.getBytes(StandardCharsets.UTF_8);
37
​
38
//Create a treasury Key
39
PrivateKey treasuryKey = PrivateKey.generateED25519();
40
​
41
//Create a treasury account
42
AccountCreateTransaction treasuryAccount = new AccountCreateTransaction()
43
.setKey(treasuryKey)
44
.setInitialBalance(new Hbar(100))
45
.setAccountMemo("treasury account");
46
​
47
//Submit the account create transaction
48
TransactionResponse submitAccountCreateTx = treasuryAccount.execute(client);
49
​
50
//Get the receipt of the transaction
51
TransactionReceipt newAccountReceipt = submitAccountCreateTx.getReceipt(client);
52
​
53
//Get the treasury account ID
54
AccountId treasuryAccountId = newAccountReceipt.accountId;
55
System.out.println("The new account ID is " +treasuryAccountId);
56
​
57
//Create a token to interact with
58
TokenCreateTransaction createToken = new TokenCreateTransaction()
59
.setTokenName("HSCS demo")
60
.setTokenSymbol("H")
61
.setTokenType(TokenType.FUNGIBLE_COMMON)
62
.setTreasuryAccountId(treasuryAccountId)
63
.setInitialSupply(500);
64
​
65
//Submit the token create transaction
66
TransactionResponse submitTokenTx = createToken.freezeWith(client).sign(treasuryKey).execute(client);
67
​
68
//Get the token ID
69
TokenId tokenId = submitTokenTx.getReceipt(client).tokenId;
70
System.out.println("The new token ID is " +tokenId);
71
​
72
​
73
//Create a file on Hedera and store the hex-encoded bytecode
74
FileCreateTransaction fileCreateTx = new FileCreateTransaction()
75
.setKeys(privateKeyTest)
76
.setContents(bytecode);
77
​
78
//Submit the file to the Hedera test network
79
TransactionResponse submitTx = fileCreateTx.execute(client);
80
​
81
//Get the receipt of the file create transaction
82
TransactionReceipt fileReceipt = submitTx.getReceipt(client);
83
​
84
//Get the file ID
85
FileId newFileId = fileReceipt.fileId;
86
​
87
//Log the file ID
88
System.out.println("The smart contract byte code file ID is " + newFileId);
89
​
90
​
91
//Deploy the contract
92
ContractCreateTransaction contractTx = new ContractCreateTransaction()
93
//The contract bytecode file
94
.setBytecodeFileId(newFileId)
95
//The max gas to reserve for this transaction
96
.setGas(2_000_000);
97
​
98
//Submit the transaction to the Hedera test network
99
TransactionResponse contractResponse = contractTx.execute(client);
100
​
101
//Get the receipt of the file create transaction
102
TransactionReceipt contractReceipt = contractResponse.getReceipt(client);
103
​
104
//Get the smart contract ID
105
ContractId newContractId = contractReceipt.contractId;
106
​
107
//Log the smart contract ID
108
System.out.println("The smart contract ID is " + newContractId);
109
​
110
//Associate the token to an account using the HTS contract
111
ContractExecuteTransaction associateToken = new ContractExecuteTransaction()
112
//The contract to call
113
.setContractId(newContractId)
114
//The gas for the transaction
115
.setGas(2_000_000)
116
//The contract function to call and parameters to pass
117
.setFunction("tokenAssociate", new ContractFunctionParameters()
118
//The account ID to associate the token to
119
.addAddress(accountIdTest.toSolidityAddress())
120
//The token ID to associate to the account
121
.addAddress(tokenId.toSolidityAddress()));
122
​
123
//Sign with the account key to associate and submit to the Hedera network
124
TransactionResponse associateTokenResponse = associateToken.freezeWith(client).sign(privateKeyTest).execute(client);
125
​
126
System.out.println("The transaction status: " +associateTokenResponse.getReceipt(client).status);
127
​
128
//Get the child token associate transaction record
129
TransactionRecord childRecords = new TransactionRecordQuery()
130
//Set the bool flag equal to true
131
.setIncludeChildren(true)
132
//The transaction ID of th parent contract execute transaction
133
.setTransactionId(associateTokenResponse.transactionId)
134
.execute(client);
135
​
136
System.out.println("The transaction record for the associate transaction" +childRecords.children.get(0));
137
​
138
//The balance of the account
139
AccountBalance accountBalance3 = new AccountBalanceQuery()
140
.setAccountId(accountIdTest)
141
.execute(client);
142
​
143
System.out.println("The " + tokenId + " should now be associated to my account: " + accountBalance3.tokens);
144
​
145
//Transfer the new token to the account
146
//Contract function params need to be in the order of the paramters provided in the tokenTransfer contract function
147
ContractExecuteTransaction tokenTransfer = new ContractExecuteTransaction()
148
.setContractId(newContractId)
149
.setGas(2_000_000)
150
.setFunction("tokenTransfer", new ContractFunctionParameters()
151
//The ID of the token
152
.addAddress(tokenId.toSolidityAddress())
153
//The account to transfer the tokens from
154
.addAddress(treasuryAccountId.toSolidityAddress())
155
//The account to transfer the tokens to
156
.addAddress(accountIdTest.toSolidityAddress())
157
//The number of tokens to transfer
158
.addInt64(100));
159
​
160
//Sign the token transfer transaction with the treasury account to authorize the transfer and submit
161
ContractExecuteTransaction signTokenTransfer = tokenTransfer.freezeWith(client).sign(treasuryKey);
162
​
163
//Submit transfer transaction
164
TransactionResponse submitTransfer = signTokenTransfer.execute(client);
165
​
166
//Get transaction status
167
Status txStatus = submitTransfer.getReceipt(client).status;
168
​
169
//Get the transaction status
170
System.out.println("The transfer transaction status " +txStatus);
171
​
172
//Verify your account received the 100 tokens
173
AccountBalance newAccountBalance = new AccountBalanceQuery()
174
.setAccountId(accountIdTest)
175
.execute(client);
176
​
177
System.out.println("My new account balance is " +newAccountBalance.tokens);
178
}
179
}
Copied!
1
require("dotenv").config();
2
​
3
const {
4
Client,
5
PrivateKey,
6
ContractCreateTransaction,
7
ContractExecuteTransaction,
8
FileCreateTransaction,
9
ContractFunctionParameters,
10
Hbar,
11
AccountId,
12
AccountCreateTransaction,
13
TokenCreateTransaction,
14
TokenType,
15
TransactionRecordQuery,
16
AccountBalanceQuery
17
} = require("@hashgraph/sdk");
18
​
19
// Import the compiled contract
20
const htsContract = require("./HTS.json");
21
​
22
async function main() {
23
//Grab your Hedera testnet account ID and private key from your .env file
24
const accountIdTest = AccountId.fromString(process.env.PREVIEWNET_ACCOUNT_ID);
25
const accountKeyTest = PrivateKey.fromStringED25519(process.env.PREVIEWNET_PRIVATE_KEY);
26
​