Skip to main content

Utilizing test tokens in dev environment

Introduction

The Cartesi CLI is one of the most important tools for developing applications with Cartesi. It provides a wide range of functionalities that simplify and automate the process of setting up, deploying, and interacting with your applications.

When you run your application using the cartesi run command, the CLI automatically spins up a Local anvil network in a Docker container. Within this network, all the required contracts are deployed such as the InputBox contract, your application contract, and Portals contract.

In addition, the CLI also deploys test token contracts by default:

  • ERC20 (TestToken)
  • ERC721 (TestNFT)
  • ERC1155 (TestMultiToken)

These contracts are owned by the Anvil's first wallet address. This ensures developers have immediate access to and ownership over these tokens for testing purposes, without the need for manual deployments. More details about the different addresses provided by anvil can be found on the Anvil official Docs.

This tutorial will guide you through using these default tokens effectively while developing in a local devnet environment.

Tokens basic Information

The following table lists the default test tokens deployed by the CLI:

TokenkeywordValue
ERC20 TokenToken NameTestToken
Token SymbolTEST
Token Decimal18
Token Address0xFBdB734EF6a23aD76863CbA6f10d0C5CBBD8342C
Contract Owner0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
ERC721 TokenToken NameTestNFT
Token SymbolSUNN
Token Address0xBa46623aD94AB45850c4ecbA9555D26328917c3B
Contract Owner0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
ERC1155 TokenToken NameTestMultiToken
Token Address0xDC6d64971B77a47fB3E3c6c409D4A05468C398D2
Contract Owner0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266

You can also view these token addresses at any time using the CLI command:

cartesi address-book

ERC20 Test Token

The ERC20 TestToken is based on the OpenZeppelin ERC20 implementation. It is deployed alongside your application contracts on the anvil devnet, with ownership assigned to the default anvil wallet 0xFBdB734EF6a23aD76863CbA6f10d0C5CBBD8342C, ensuring that developers can readily access these test tokens without needing to manually deploy or transfer new token contracts. However, you can transfer these tokens to other wallets and also to your applications for the duration of which your anvil network is active as these transactions reset every time you restart your anvil devnet, or stop your application using the Cartesi CLI.

Minting ERC20 Test Tokens

Minting new tokens on the TestToken is currently disabled, but at deployment 1000000000 * 10 units of the token was minted to the default anvil wallet 0xFBdB734EF6a23aD76863CbA6f10d0C5CBBD8342C, this amount should be more than suitable for testing your application. With that covered, we can proceed to transferring and also depositing these tokens to your application.

Transferring the ERC20 Test Token to other wallets

When testing interactions that require multiple addresses (e.g., deposits from different users), you may need to transfer tokens from the owner account to other wallets. For this example, we’ll use the second Anvil address as the recipient. You can change the recipient to any address of your choice.

Using Cast Command

cast send <testTokenContract address> "transfer(address,uint256)" <receivers address> <token amount> --rpc-url <rpc_url> --private-key <private key>

The above command calls the transfer(address,uint256) in the testToken contract 0xFBdB7...8342C. The command passes the following argument to the function: receivers address= 0x709979...c79C8and amount= 202. While you can always change the amount argument to match what you intend to deposit to your application, it's important to always maintain the same testToken contract as well as the private-key 0xac0974b...f2ff80.

Depositing the ERC20 Test Token to your application

Similar to mainnet, applications undergoing development or testing on devnet can also receive erc20 tokens deposit, it is essential that your application includes the proper logic to receive and also record token deposit. This example will guide you through the process of depositing the test token to your application and also how to properly decode the deposit data sent to your application.

There are two main approaches:

Using the CLI

  • Ensure you have your Cartesi application running, then from project directory, open a terminal and run the below command:
cartesi deposit
  • Select ERC20 from the list of deposit options.

  • The next menu requests for a token address, but has the TestToken address filled but grayed out, hit the enter button to use the TestToken.

  • In the next menu, enter the amount to tokens, you intend to deposit then finally hit enter.

  • This would trigger the approval process, then deposit the tokens to your application.

For a successful deposit process you should show logs similar to this:

✔ Select type of asset to deposit erc20
✔ Token address 0xFBdB734EF6a23aD76863CbA6f10d0C5CBBD8342C
✔ Amount (TEST) 202
✔ Approved 202 TEST
✔ Deposited 202 TEST to 0xba3347e79665924033beeb7362629ca7992897d9

Using Cast

It's also possible to use cast commands to deposit assets to your application, but this would require a more manual process of granting approval, then calling the deposit function in the ERC20Portal contract. Below is a step-by-step process to achieve this:

  • Call the testToken contract to approve the ERC20Portal an equivalent of the amount of tokens you intend to deposit, using the below command
cast send <testsTokenContract address> "approve(address,uint256)" <ERC20Portal address> <Token amount> --rpc-url <RPC_URL> --private-key <Caller Private key>

The snippet above is an example of how to deposit 300 units of the test tokens, http://127.0.0.1:6751/anvil is the anvil_rpc to the local devnet where the application contract is deployed, finally the private_key 0xac0974bec39a17...e784d7bf4f2ff80 is the private key of the default anvil address which is also the owner of the erc20 test contract.

  • Call the depositERC20Tokens function in the ERC20Portal contract, passing in the address of your contract along with the token address and amount of tokens deposited
cast send <ERC20Portal address> "depositERC20Tokens(address,address,uint256,bytes)" <testTokenContract address> <Application address> <token_Amount> <execution layer Data> --rpc-url <RPC_URL> --private-key <Caller Private key>

The above command interacts with the ERC20Portal which utilizes the allowance issued in the previous function to call the transferFrom function in the testToken contract. This operation transfers the amount of tokens listed to the application contract, and calls the input box to send an input to your application.

The next section covers implementations on your application to handle deposits.

Handling Deposited ERC20 tokens

One important part of the deposit workflow is the decoding of the inputs. It is an important and delicate process, requiring accurate decoding as errors in this section could lease to unaccounted deposits.

While the previous example, help deposit tokens to your applications, without proper logic implementation, your application will be unable to record and track tokens deposited by users. The below code snippet is a simple application designed to receive deposit calls, decode, then finally log the data it received. You can test the application through the following steps:

  • Create a new JavaScript application, using the command:
cartesi create deposit-erc20 --template javascript
  • CD into the new project then copy and paste the below code snippet into index page.
import { ethers } from "ethers";
import {
getAddress,
} from "viem";

const rollup_server = process.env.ROLLUP_HTTP_SERVER_URL;
console.log("HTTP rollup_server url is " + rollup_server);

const PORTAL_ADDRESS = "0xc700D6aDd016eECd59d989C028214Eaa0fCC0051";


function parseDepositPayload(payload) {
const tokenData = ethers.dataSlice(payload, 0, 20);
const senderData = ethers.dataSlice(payload, 20, 40);
const amountData = ethers.dataSlice(payload, 40, 72);

if (!tokenData) {
throw new Error("Invalid deposit payload");
}
return [getAddress(tokenData), getAddress(senderData), BigInt(amountData)];
}

async function handle_advance(data) {
console.log("Received advance request data " + JSON.stringify(data));
let payload = data.payload;
const sender = data["metadata"]["msg_sender"];

if (sender.toLowerCase() === PORTAL_ADDRESS.toLowerCase()) {
console.log("Handling portal deposit");
const [token, depositor, amount] = parseDepositPayload(payload);
console.log(`Token: ${token}, Depositor: ${depositor}, Amount: ${amount}`);

// Handle deposit logic here
} else {
// Handle Transaction request like a regular transaction
}

return "accept";
}

async function handle_inspect(data) {
console.log("Received inspect request data " + JSON.stringify(data));
return "accept";
}

var handlers = {
advance_state: handle_advance,
inspect_state: handle_inspect,
};

var finish = { status: "accept" };

(async () => {
while (true) {
const finish_req = await fetch(rollup_server + "/finish", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ status: "accept" }),
});

console.log("Received finish status " + finish_req.status);

if (finish_req.status == 202) {
console.log("No pending rollup request, trying again");
} else {
const rollup_req = await finish_req.json();
var handler = handlers[rollup_req["request_type"]];
finish["status"] = await handler(rollup_req["data"]);
}
}
})();
  • Install necessary dependencies for rust or javasctipt by running the command:
npm install viem ethers
  • Build and run your application using the command:
cartesi build

cartesi run
  • In a new terminal, ensure you're in the directory of your Cartesi application then run deposit command and follow though on the prompts to deposit an ERC20 token.
cartesi deposit

On successful deposit your application should log an object containing the deposited token, depositor and finally the amount deposited.

Sample Log

[INFO  rollup_http_server::http_service] received new request of type ADVANCE
[INFO actix_web::middleware::logger] 127.0.0.1 "POST /finish HTTP/1.1" 200 495 "-" "node" 0.032192
Received finish status 200
Received advance request data {"metadata":{"chain_id":13370,"app_contract":"0xba3347e79665924033beeb7362629ca7992897d9","msg_sender":"0xc700d6add016eecd59d989c028214eaa0fcc0051","block_number":823,"block_timestamp":1757042397,"prev_randao":"0xf1db9cff537dd607f721ef4aee7d2b516d4adb7fbb0d1c707b72344527e6893e","input_index":0},"payload":"0xfbdb734ef6a23ad76863cba6f10d0c5cbbd8342cf39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000c93a592cfb2a00000"}
Handling portal deposit
Token: 0xFBdB734EF6a23aD76863CbA6f10d0C5CBBD8342C, Depositor: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, Amount: 232000000000000000000

ERC721 Test Tokens

The ERC721 test token is an Openzeppelin implementation of an ERC721 token, similar to other test tokens it's ownership is also set to the default address provided by anvil, therefore interactions with restricted functions on this contract would need to be signed by the default anvil private key 0xf39fd...b92266. Using the right authorizations you could mint, transfer and also deposit these tokens to other address as well as your application. In the example below, we'll be covering minting, transferring and finally depositing testNFT tokens.

Minting the ERC721 Test Tokens

Using Cast

cast send <testNFT address> "safeMint(address,uint256,string)" <receivers address> <token id> <token URI> --rpc-url <rpc_url> --private-key <caller private key>

The above example calls the safeMint function in the testNFT contract 0xBa4662...917c3B specifying the receivers address 0xf39Fd6...2266, the token id 1 and finally the URI for the token https://example.com/metadata/1.json. The receivers address, token ID and token URI specified above can all be changed to match your test case but, it's important that the testNFT address as well as the private_key be the same.

Transferring The ERC721 Test Tokens

Using Cast

cast send <testNFT address> "transferFrom(address,address,uint256)" <senders address> <receivers address> <token id>--rpc-url http://127.0.0.1:6751/anvil --private-key <caller private key>

This command utilizes cast to call the transferFrom function in the TestNft contract 0xBa4662...917c3B. The function takes the following arguments: senders address=0xf39Fd6...92266, receivers address = 0x709979...dc79C8 and token_id = 2. While the function arguments passed can be modified, it's important that the senders address is the address of the wallet which owns the token with the token ID specified, and also that the private key passed is correct private key for the senders' wallet address

Depositing the ERC721 Test Tokens

Depositing the ERC721 test tokens follow a similar process with depositing ERC20 tokens, this can be done either through cast or through the Cartesi CLI. Cast offers a more manual approach while using the CLI automates and simplifies the process.

Using the CLI

  • Ensure you have your Cartesi application running, then from project directory, open a terminal and run the below command:
cartesi deposit
  • Select ERC721 from the list of available transfer options.

  • The next menu requests for token ID, pass the ID of the token you intend to deposit.

  • The next menu requests for a token address, but has the TestNFT address filled but grayed out, hit the enter button to use the TestNFT, or enter the address of another deployed token.

  • This will trigger the approval process, if successful it'll proceed to trigger the deposit process, then transfer the tokens to your application.

For a successful deposit process you should get a log similar to this below:

✔ Select type of asset to deposit erc721
✔ Token ID 1
✔ Token address 0xBa46623aD94AB45850c4ecbA9555D26328917c3B
✔ Approved undefined SUNN
✔ Deposited undefined SUNN to 0xba3347e79665924033beeb7362629ca7992897d9

Using Cast

It's also possible to deposit the ERC721 test tokens to your application using Cast, this process, requires a more manual approach and happens in 2 phases, one is granting approval to the ERC721Portal then the second is calling the depositERC721Token function in the ERC721Portal contract. Below is a step-by-step process for this:

  • Grant the ERC721Portal contract approval
cast send <testNFT address> "setApprovalForAll(address,bool)" <ERC721Portal address> <approved status> --rpc-url <RPC_URL> --private-key <Caller Private key>

The above command calls the testNFT contract 0xBa46...8917c3B to approve the ERC721Portal 0xc700d5...0051 to withdraw tokens to be deposited to your application, the arguments listed above should be the same if you intend to deposit the testNFT token, for other ERC721 tokens, then you could change the token address to match the tokens you intend to transfer.

  • Call the depositERC721Token function in the ERC721Portal contract
cast send <ERC721Portal address> "depositERC721Token(address,address,uint256,bytes,bytes)" <testNFT Contract address> <Application address>  <token_Id> <base layer Data>  <execution layer Data> --rpc-url <RPC_URL> --private-key <Caller Private key>

From the above command we call the depositERC721Token function in the ERC721Portal contract 0xc700...60051, passing the testNFT contract 0xBa46...8917c3B, the Application contract address 0x23eff...560fc, the token_id 4 and finally the optional baseLayer and executionLayer data 0x and 0x. For this implementation it's expected that the token_id passed to the function should already be minted and owned by the wallet whose private key is used to sign the transaction.

Handling Deposited ERC721 tokens

The below example is a process flow to setup and test a simple application designed to receive deposit input, decode, then finally log the data it received. You can run the application through the following steps:

  • Create a new JavaScript application, using the command:
cartesi create deposit-erc721 --template javascript
  • CD into the new project then, copy and paste the below code snippet into the index file.
import { ethers } from "ethers";
import {
getAddress,
} from "viem";

const rollup_server = process.env.ROLLUP_HTTP_SERVER_URL;
console.log("HTTP rollup_server url is " + rollup_server);

const ERC721_PORTAL_ADDRESS = "0xc700d52f5290e978e9cae7d1e092935263b60051";


function parseDepositPayload(payload) {
const tokenData = ethers.dataSlice(payload, 0, 20);
const senderData = ethers.dataSlice(payload, 20, 40);
const tokenIdData = ethers.dataSlice(payload, 40, 72);

if (!tokenData) {
throw new Error("Invalid deposit payload");
}
return [getAddress(tokenData), getAddress(senderData), BigInt(tokenIdData)];
}

async function handle_advance(data) {
console.log("Received advance request data " + JSON.stringify(data));
let payload = data.payload;
const sender = data["metadata"]["msg_sender"];

if (sender.toLowerCase() === ERC721_PORTAL_ADDRESS.toLowerCase()) {
console.log("Handling portal deposit");
const [token, depositor, amount] = parseDepositPayload(payload);
console.log(`Token: ${token}, Depositor: ${depositor}, Amount: ${amount}`);

// Handle deposit logic here
} else {
// Handle Transaction request like a regular transaction
}

return "accept";
}

async function handle_inspect(data) {
console.log("Received inspect request data " + JSON.stringify(data));
return "accept";
}

var handlers = {
advance_state: handle_advance,
inspect_state: handle_inspect,
};

var finish = { status: "accept" };

(async () => {
while (true) {
const finish_req = await fetch(rollup_server + "/finish", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ status: "accept" }),
});

console.log("Received finish status " + finish_req.status);

if (finish_req.status == 202) {
console.log("No pending rollup request, trying again");
} else {
const rollup_req = await finish_req.json();
var handler = handlers[rollup_req["request_type"]];
finish["status"] = await handler(rollup_req["data"]);
}
}
})();

  • Install necessary dependencies for rust or javascript by running the command:
npm install viem ethers
  • Build and run your application using the command:
cartesi build

cartesi run
  • In a new terminal, ensure you're in the directory of your Cartesi application then run deposit command and follow though on the prompts to deposit an ERC20 token.
cartesi deposit

On successful deposit your application should log an object containing the deposited token, depositor and finally the amount deposited.

Sample Log

[INFO  rollup_http_server::http_service] received new request of type ADVANCE
[INFO actix_web::middleware::logger] 127.0.0.1 "POST /finish HTTP/1.1" 200 753 "-" "node" 0.032320
Received finish status 200
Received advance request data {"metadata":{"chain_id":13370,"app_contract":"0xba3347e79665924033beeb7362629ca7992897d9","msg_sender":"0xc700d52f5290e978e9cae7d1e092935263b60051","block_number":24284,"block_timestamp":1757089398,"prev_randao":"0x1b76a6830d8a66d5908c517264984bde0ae7ecb9827d8ab4530066ce2a8f1ad0","input_index":0},"payload":"0xba46623ad94ab45850c4ecba9555d26328917c3bf39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
Handling portal deposit
Token: 0xBa46623aD94AB45850c4ecbA9555D26328917c3B, Depositor: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, Token_id: 7

ERC1155 Tokens

The ERC155 test token is also an Openzeppelin implementation of an ERC1155 token called TestMultiToken, like the other two, it is owned by the default anvil wallet and managed by the Cartesi CLI, below is a guide on, minting, transferring and depositing, this token to other wallets and also your Cartesi application.

Minting ERC1155 Test Tokens

Minting the ERC1155 token issues new tokens to a selected wallet address, this function is restricted to just the owner of the contract, so it's necessary that the transaction be signed by the default anvil private key.

Using Cast

cast send <TestMultiToken contract address> "mint(address,uint256,uint256,bytes)" <receivers address> <token_id> <Token_amount> <data> --rpc-url <RPC_URL> --private-key <Caller Private key>

The above example we call the mint function in the TestMultiToken contract 0xDC6d...98D2, to mint 1 unit of the token with id 1 to the receivers address 0xf39F...92266. The function arguments passed to this function can be modified, but it's necessary that the private key remain the same as the owner of the TestMultiToken contract is set to the default anvil wallet with the private key 0xac097...f2ff80.

Transferring ERC1155 Test Tokens

Using Cast

cast send <TestMultiToken contract address> "safeTransferFrom(address,address,uint256,uint256,bytes)" <senders address> <receivers address> <token_id> <Token_amount> <data> --rpc-url <RPC_URL> --private-key <Caller Private key>

The above command interacts with the safeTransferFrom function of the TestMultiToken contract 0xDC6d...98D2. The command transfers 1 unit of the token with id 1 from the owner address 0xf39F...92266 to the receiver address 0x7099...dc79C8, this transaction is signed using the private key for the owner address specified.

Depositing ERC1155 Tokens

Using The CLI

  • Run your Cartesi application.

  • From the project directory, open a terminal and run:

cartesi deposit
  • From the available options, select erc1155-single if you intend to deposit a single token, or select erc1155-batch if you're depositing multiple tokens at once.

  • Accept the pre-filled TestToken address (or enter another ERC1155 token address).

  • Enter the ID of the token you intend to deposit, if multiple you can add all of their ID's separated by commas.

  • In the next menu enter the amount of tokens you intend to deposit (separate them by comma's if multiple).

  • The CLI would automatically run the approval then the deposit process for the tokens. On successful deposit you should see logs similar to this:

✔ Select type of asset to deposit erc1155-single
✔ Token address 0xDC6d64971B77a47fB3E3c6c409D4A05468C398D2
✔ Token ID 5
✔ Amount of token ID 5 1
✔ Approved ERC1155Portal
✔ Deposited 1 units of token id 5 to 0x0c0fe740dcd46f0a6ddb8498d0bfdca93c5910e6

Using Cast

  • Grant the ERC1155SinglePortal contract approval
cast send <TestMultiToken contract address> "setApprovalForAll(address,bool)" <ERC1155SinglePortal address> <approved status> ---rpc-url <RPC_URL> --private-key <Caller Private key>
  • Call the depositSingleERC1155Token function in the ERC1155SinglePortal contract
cast send <ERC1155SinglePortal Contract address> "depositSingleERC1155Token(address,address,uint256,uint256,bytes,bytes)" <TestMultiToken Contract address> <Application address> <token_id> <Token_amount> <base layer Data>  <execution layer Data>  ---rpc-url <RPC_URL> --private-key <Caller Private key>

Handling Deposited ERC1155 tokens

This sections provides sample codes and also a step by step guide to design and test the deposit flow for ERC1155 tokens.

  • Create a new JavaScript application, using the command:
cartesi create deposit-erc1155 --template javascript
  • CD into the new project then, copy and paste the below code snippet into the index file.
import { ethers } from "ethers";
import {
getAddress,
} from "viem";

const rollup_server = process.env.ROLLUP_HTTP_SERVER_URL;
console.log("HTTP rollup_server url is " + rollup_server);

const ERC1155_SINGLE_PORTAL_ADDRESS = "0xc700A261279aFC6F755A3a67D86ae43E2eBD0051";


function parseDepositPayload(payload) {
const tokenData = ethers.dataSlice(payload, 0, 20);
const senderData = ethers.dataSlice(payload, 20, 40);
const tokenIdData = ethers.dataSlice(payload, 40, 72);
const amountData = ethers.dataSlice(payload, 72, 104);

if (!tokenData) {
throw new Error("Invalid deposit payload");
}
return [getAddress(tokenData), getAddress(senderData), BigInt(tokenIdData), BigInt(amountData)];
}

async function handle_advance(data) {
console.log("Received advance request data " + JSON.stringify(data));
let payload = data.payload;
const sender = data["metadata"]["msg_sender"];

if (sender.toLowerCase() === ERC1155_SINGLE_PORTAL_ADDRESS.toLowerCase()) {
console.log("Handling portal deposit");
const [token, depositor, tokenId, amount] = parseDepositPayload(payload);
console.log(`Token: ${token}, Depositor: ${depositor}, Token ID: ${tokenId}, Amount: ${amount}`);

// Handle deposit logic here
} else {
// Handle Transaction request like a regular transaction
}

return "accept";
}

async function handle_inspect(data) {
console.log("Received inspect request data " + JSON.stringify(data));
return "accept";
}

var handlers = {
advance_state: handle_advance,
inspect_state: handle_inspect,
};

var finish = { status: "accept" };

(async () => {
while (true) {
const finish_req = await fetch(rollup_server + "/finish", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ status: "accept" }),
});

console.log("Received finish status " + finish_req.status);

if (finish_req.status == 202) {
console.log("No pending rollup request, trying again");
} else {
const rollup_req = await finish_req.json();
var handler = handlers[rollup_req["request_type"]];
finish["status"] = await handler(rollup_req["data"]);
}
}
})();
  • Install necessary dependencies for rust or javasctipt by running the command:
npm install viem ethers
  • Build and run your application using the command:
cartesi build

cartesi run
  • In a new terminal, ensure you're in the directory of your Cartesi application then run deposit command and follow though on the prompts to deposit an ERC20 token.
cartesi deposit

On successful deposit your application should log an object containing the deposited token, depositor and finally the amount deposited.

Sample Log

[INFO  rollup_http_server::http_service] received new request of type ADVANCE
[INFO actix_web::middleware::logger] 127.0.0.1 "POST /finish HTTP/1.1" 200 814 "-" "python-requests/2.31.0" 0.020416
INFO:__main__:Received finish status 200
INFO:__main__:Received advance request data {'metadata': {'chain_id': 13370, 'app_contract': '0x1f6eb23dfa21f9013ee83c4e09a93b494736d7d9', 'msg_sender': '0xc700a261279afc6f755a3a67d86ae43e2ebd0051', 'block_number': 21, 'block_timestamp': 1757624870, 'prev_randao': '0x45c3ecf672b0c35d25c822ccb22f145f633feec5451438436f57fd310366df44', 'input_index': 0}, 'payload': '0xdc6d64971b77a47fb3e3c6c409d4a05468c398d2f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'}
INFO:__main__:Token: 0xdc6d64971b77a47fb3e3c6c409d4a05468c398d2, Depositor: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266, token ID: 1 token_amount: 1
INFO:__main__:Sending finish
We use cookies to ensure that we give you the best experience on our website. By using the website, you agree to the use of cookies.