github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/examples/precompile_example/PrecompileExample.sol (about) 1 // SPDX-License-Identifier: Apache-2.0 2 pragma solidity >=0.5.0 <0.9.0; 3 pragma experimental ABIEncoderV2; 4 5 import "./ExpiryHelper.sol"; 6 import "./PrngSystemContract.sol"; 7 import "./KeyHelper.sol"; 8 import "./HederaTokenService.sol"; 9 import "./FeeHelper.sol"; 10 11 // To alter the behavior of the SolidityPrecompileExample, re-compile this solidity file 12 // (you will also need the other files in this directory) 13 // and copy the outputted json file to ./PrecompileExample.json 14 15 contract PrecompileExample is 16 PrngSystemContract, 17 HederaTokenService, 18 ExpiryHelper, 19 KeyHelper, 20 FeeHelper 21 { 22 address payable owner; 23 address payable aliceAccount; 24 address fungibleToken; 25 address nftToken; 26 27 constructor(address payable _owner, address payable _aliceAccount) { 28 owner = _owner; 29 aliceAccount = _aliceAccount; 30 } 31 32 function step0() external returns (bytes32 result) { 33 require(msg.sender == owner); 34 35 result = this.getPseudorandomSeed(); 36 } 37 38 // In order for some functions (such as createFungibleToken) to work, the contract must possess the funds for 39 // the function call. We are using ContractExecuteTransaction.setPayableAmount() to transfer some Hbar 40 // to the contract's account at each step (which means this function must be payable), and then transferring 41 // the excess Hbar back to the owner at the end of each step. 42 function step1() external payable returns (int responseCode) { 43 require(msg.sender == owner); 44 45 IHederaTokenService.TokenKey[] 46 memory keys = new IHederaTokenService.TokenKey[](4); 47 keys[0] = getSingleKey( 48 KeyType.ADMIN, 49 KeyType.PAUSE, 50 KeyValueType.INHERIT_ACCOUNT_KEY, 51 bytes("") 52 ); 53 54 keys[1] = getSingleKey( 55 KeyType.FREEZE, 56 KeyValueType.INHERIT_ACCOUNT_KEY, 57 bytes("") 58 ); 59 keys[2] = getSingleKey( 60 KeyType.WIPE, 61 KeyValueType.INHERIT_ACCOUNT_KEY, 62 bytes("") 63 ); 64 keys[3] = getSingleKey( 65 KeyType.SUPPLY, 66 KeyValueType.INHERIT_ACCOUNT_KEY, 67 bytes("") 68 ); 69 70 //KeyType.SUPPLY KeyType.FREEZE, 71 (responseCode, fungibleToken) = createFungibleToken( 72 IHederaTokenService.HederaToken( 73 "Example Fungible token", // name 74 "E", // symbol 75 address(this), // treasury 76 "memo", 77 true, // supply type, false -> INFINITE, true -> FINITE 78 1000, // max supply 79 false, // freeze default (setting to false means that this token will not be initially frozen on creation) 80 keys, // the keys for the new token 81 // auto-renew fee paid by aliceAccount every 7,000,000 seconds (approx. 81 days). 82 // This is the minimum auto renew period. 83 createAutoRenewExpiry(address(this), 7000000) 84 ), 85 100, // initial supply 86 0 // decimals 87 ); 88 89 // send any excess Hbar back to the owner 90 owner.transfer(address(this).balance); 91 } 92 93 function step2() external returns (int responseCode) { 94 require(msg.sender == owner); 95 96 int64 newTotalSupply; 97 int64[] memory mintedSerials; // applicable to NFT tokens only 98 (responseCode, newTotalSupply, mintedSerials) = mintToken( 99 fungibleToken, 100 100, // amount (applicable to fungible tokens only) 101 new bytes[](0) // metadatas (applicable to NFT tokens only) 102 ); 103 104 require(newTotalSupply == 100 + 100); 105 } 106 107 function step3() external returns (int responseCode) { 108 require(msg.sender == owner); 109 110 responseCode = associateToken(aliceAccount, fungibleToken); 111 } 112 113 function step4() external returns (int responseCode) { 114 require(msg.sender == owner); 115 116 responseCode = transferToken( 117 fungibleToken, 118 address(this), // sender 119 aliceAccount, // receiver 120 100 // amount to transfer 121 ); 122 } 123 124 function step5() external returns (int responseCode) { 125 require(msg.sender == owner); 126 127 // this contract will be the allowance owner 128 responseCode = approve( 129 fungibleToken, 130 aliceAccount, // spender 131 100 // amount 132 ); 133 } 134 135 function step6() external returns (int responseCode) { 136 require(msg.sender == owner); 137 138 responseCode = HederaTokenService.pauseToken(fungibleToken); 139 } 140 141 function step7() external returns (int responseCode) { 142 require(msg.sender == owner); 143 144 responseCode = HederaTokenService.unpauseToken(fungibleToken); 145 } 146 147 function step8() external returns (int responseCode) { 148 require(msg.sender == owner); 149 150 responseCode = freezeToken(fungibleToken, aliceAccount); 151 } 152 153 function step9() external returns (int responseCode) { 154 require(msg.sender == owner); 155 156 responseCode = unfreezeToken(fungibleToken, aliceAccount); 157 } 158 159 function step10() external returns (int responseCode) { 160 require(msg.sender == owner); 161 162 int64 totalSupplyLeftAfterBurn; 163 (responseCode, totalSupplyLeftAfterBurn) = burnToken( 164 fungibleToken, 165 50, // amount to burn (applicable to fungible tokens only) 166 new int64[](0) // serial numbers to burn (applicable to NFT tokens only) 167 ); 168 169 require(totalSupplyLeftAfterBurn == 100 + 100 - 50); 170 } 171 172 function step11( 173 bytes memory keyBytes 174 ) external payable returns (int responseCode, address) { 175 require(msg.sender == owner); 176 177 IHederaTokenService.TokenKey[] 178 memory keys = new IHederaTokenService.TokenKey[](1); 179 // Set the admin key and the supply key to given ED25519 public key bytes. 180 // These must be the key's raw bytes acquired via key.toBytesRaw() 181 182 keys[0] = getSingleKey( 183 KeyType.ADMIN, 184 KeyType.SUPPLY, 185 KeyValueType.ED25519, 186 keyBytes 187 ); 188 189 IHederaTokenService.FixedFee[] 190 memory fixedFees = new IHederaTokenService.FixedFee[](1); 191 // Create a fixed fee of 1 Hbar (100,000,000 tinybar) that is collected by owner 192 fixedFees[0] = createFixedFeeForHbars(100000000, owner); 193 194 (responseCode, nftToken) = createNonFungibleTokenWithCustomFees( 195 IHederaTokenService.HederaToken( 196 "Example NFT token", // name 197 "ENFT", // symbol 198 address(this), // treasury 199 "memo", 200 true, // supply type, false -> INFINITE, true -> FINITE 201 1000, // max supply 202 false, // freeze default (setting to false means that this token will not be initially frozen on creation) 203 keys, // the keys for the new token 204 // auto-renew fee paid by aliceAccount every 7,000,000 seconds (approx. 81 days). 205 // This is the minimum auto renew period. 206 createAutoRenewExpiry(address(this), 7000000) 207 ), 208 fixedFees, 209 new IHederaTokenService.RoyaltyFee[](0) 210 ); 211 212 // send any excess Hbar back to the owner 213 owner.transfer(address(this).balance); 214 return (responseCode, nftToken); 215 } 216 217 function step12( 218 bytes[] memory metadatas 219 ) external returns (int responseCode) { 220 require(msg.sender == owner); 221 require(metadatas.length == 3); 222 223 int64 mintedCount; 224 int64[] memory mintedSerials; // applicable to NFT tokens only 225 (responseCode, mintedCount, mintedSerials) = mintToken( 226 nftToken, 227 0, // amount (applicable to fungible tokens only) 228 metadatas // (applicable to NFT tokens only) 229 ); 230 231 require(mintedCount == 3); 232 require(mintedSerials.length == 3); 233 require(mintedSerials[0] == 1); 234 require(mintedSerials[1] == 2); 235 require(mintedSerials[2] == 3); 236 } 237 238 function step13() external returns (int responseCode) { 239 require(msg.sender == owner); 240 241 responseCode = associateToken(aliceAccount, nftToken); 242 } 243 244 function step14() external returns (int responseCode) { 245 require(msg.sender == owner); 246 247 // You may also use transferNFTs to transfer more than one serial number at a time 248 249 responseCode = transferNFT( 250 nftToken, 251 address(this), // sender 252 aliceAccount, // receiver 253 1 // serial number 254 ); 255 } 256 257 function step15() external returns (int responseCode) { 258 require(msg.sender == owner); 259 260 responseCode = approveNFT(nftToken, aliceAccount, 2); 261 } 262 263 function step16() external returns (int responseCode) { 264 require(msg.sender == owner); 265 266 int64[] memory serialsToBurn = new int64[](1); 267 serialsToBurn[0] = 3; 268 269 int64 totalSupplyLeftAfterBurn; 270 (responseCode, totalSupplyLeftAfterBurn) = burnToken( 271 nftToken, 272 0, // amount to burn (applicable to fungible tokens only) 273 serialsToBurn 274 ); 275 276 require(totalSupplyLeftAfterBurn == 2); 277 } 278 }