How to interact with and configure a smart contract on the Quai Ledger.
참고: 이 페이지는 아직 한국어로 번역되지 않았습니다. 아래는 영어 원문입니다.
This guide does not cover smart contract deployment. To learn more about deploying a smart contract with Quais and Hardhat, visit the
Hardhat Deployment Tutorial.
All operations that occur on the Quai ledger must be encoded as binary data. To call and interpret data from smart contracts on-chain, we need a simple way to convert between common data types (e.g. strings and numbers) and their binary representaion that the smart contract can understand.Quais uses ABI fragments to encode and interpret smart contract data, allowing developers to easily pass and read data from smart contracts. There are several common formats that Quais accepts to describe a smart contract’s ABI. The Solidity compiler typically provides a JSON ABI for every compiled contract that can be passed to Quais.
Copy
Ask AI
// JSON ABIconst abi = [ { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, ...]// use the JSON ABI to create a contractconst contract = new quais.Contract(address, abi, provider)
You may also provide the more readable Solidity signature for any relevant methods, errors, or calls to the contract.
Copy
Ask AI
// simplified Solidity signature ABIconst abi = [ 'function decimals() view returns (uint8)', 'function symbol() view returns (string)', 'function balanceOf(address addr) view returns (uint)',]// use the simplified ABI to create a contractconst contract = new quais.Contract(address, abi, provider)
Contracts often have read-only methods (view and pure) that can be called to query the state of the smart contract without initiating a transaction. You can call these methods using only a Provider.
Copy
Ask AI
// contract ABI (only includes the methods we care about)const abi = [ 'function decimals() view returns (uint8)', 'function symbol() view returns (string)', 'function balanceOf(address addr) view returns (uint)',]// create contract with only a Providerconst contract = new quais.Contract(address, abi, provider)// get the token symbolsymbol = await contract.symbol() // "ABC"// get the token decimalsdecimals = await contract.decimals() // 18n// get the balance of an addressbalance = await contract.balanceOf('0x1234567890123456789012345678901234567890') // 10000000000000000000n// format the balanceformatUnits(balance, decimals) // "10.0"
To call a state-changing method, you’ll need to pass a Signer or Wallet to the contract.
Copy
Ask AI
// contract ABI (only includes the methods we care about)const abi = ['function transferTo(address to, uint amount)']// create wallet and pass it to the contractconst wallet = new quais.Wallet(privateKey, provider)const contract = new quais.Contract(address, abi, wallet)// transfer some tokensconst tx = await contract.transferTo('0x1234567890123456789012345678901234567890', parseUnits('1.0', 18))await tx.wait()
You can listen for emitted events from a smart contract using event filters.
Copy
Ask AI
// contract ABI (only includes the events we care about)const abi = ['event Transfer(address indexed from, address indexed to, uint amount)']// create contract with only a Providerconst contract = new quais.Contract(address, abi, provider)// use an event listener to listen for any transfer eventcontract.on('Transfer', (from, to, amount, event) => { const tokenAmount = formatUnits(amount, 18) console.log('Transfer from', from, 'to', to, 'amount', tokenAmount) // stop listening for events event.removeListener()})// use a filter to listen for transfer events from a specific addressconst filter = contract.filters.Transfer('0x1234567890123456789012345678901234567890')contract.on(filter, (from, to, amount, event) => { const tokenAmount = formatUnits(amount, 18) console.log('Transfer from', from, 'to', to, 'amount', tokenAmount)})
To query historic events, you can use the queryFilter method.
Copy
Ask AI
// contract ABIconst abi = ['event Transfer(address indexed from, address indexed to, uint amount)']// create contract with only a Providerconst contract = new quais.Contract(address, abi, provider)// query the last 50 blocks for any transfer eventsconst filter = contract.filters.Transferconst events = await contract.queryFilter(filter, -50) // returns an array of events// query all transfer events from a specific addressconst filter = contract.filters.Transfer('0x1234567890123456789012345678901234567890')const events = await contract.queryFilter(filter) // returns an array of events