Abi
如何以程式方式為智能合約交易生成數據有效負載?
一些錢包,例如 Gnosis Safe 多重簽名,沒有 web3.js 支持或內置 ABI 編碼器。如何創建呼叫智能合約功能並源自此類錢包的交易?
您需要有智能合約的 ABI 文件。然後,您可以使用 Node.js 控制台、JavaScript 或 TypeScript 生成有效負載,
Data
以觸發交易的智能合約函式呼叫。撥打此類電話的步驟
- 獲取智能合約所需的 ABI 文件,通常來自 Github
- 為 ABI 編碼創建一個粘貼在 Node.js 控制台中的程式碼段。
- 獲取此程式碼段的結果以
Data
在事務中使用- 創建一個新事務。
To
欄位是智能合約地址,Data
值是腳本 ABI 編碼的結果。這是一個使用 TypeScript 和 OpenZeppelin SDK 製作數據負載以供
approve()
呼叫的範例。import { ZWeb3, Contracts } from '@openzeppelin/upgrades'; import { createProvider } from './src/utils/deploy'; const INFURA_PROJECT_ID = '...'; async function run(): Promise<void> { // Initialze const provider = createProvider([], INFURA_PROJECT_ID, 'mainnet'); ZWeb3.initialize(provider); // Instiate contracts const DawnTokenImpl = Contracts.getFromLocal('DawnTokenImpl'); const TokenSwap = Contracts.getFromLocal('TokenSwap'); const token = DawnTokenImpl.at('0x580c8520dEDA0a441522AEAe0f9F7A5f29629aFa'); const tokenSwap = DawnTokenImpl.at('0x2e776B7BFb8E8307E476BA4B77B21D4532ed47d2'); const holder = '0xedae4cfB12ECfCDE46853f63aBa76D8EA3CF3871'; // Read the full balance of the multisig wallet const allOfBalance = await token.methods.balanceOf(holder).call(); // Approve this balance to be used for the token swap const dataPayload = token.methods.approve(tokenSwap.address, allOfBalance).encodeABI(); console.log('Data payload for approve() tx is', dataPayload); } run();
範例輸出是
Data payload for approve() tx is 0x095ea7b30000000000000000000000002e776b7bfb8e8307e476ba4b77b21d4532ed47d20000000000000000000000000000000000000000004d50b9c6c40cb6192cfce0
對於Gnosis MultiSigWallet,我使用以下內容:
function submitTransaction(options, msWalletAddr, contractAddr, contractAbi, functionName, functionArgs, privateKey) { return sign(options, msWalletAddr, "submitTransaction", [contractAddr, "0", encode(contractAbi, functionName, functionArgs)], privateKey); } function confirmTransaction(options, msWalletAddr, transactionId, privateKey) { return sign(options, msWalletAddr, "confirmTransaction", [transactionId], privateKey); } function executeTransaction(options, msWalletAddr, transactionId, privateKey) { return sign(options, msWalletAddr, "executeTransaction", [transactionId], privateKey); } function revokeConfirmation(options, msWalletAddr, transactionId, privateKey) { return sign(options, msWalletAddr, "revokeConfirmation", [transactionId], privateKey); }
該
options
參數是一個包含以下欄位的對象:
price
(天然氣價格)limit
(氣體限制)nonce
(交易隨機數)功能
sign
和encode
實現如下:const EthereumTx = require("ethereumjs-tx"); function sign(options, msWalletAddr, actionName, actionArgs, privateKey) { const params = { value : 0, chainId : 1, gasPrice: Number(options.price), gasLimit: Number(options.limit), nonce : Number(options.nonce), to : msWalletAddr, data : encode(MultiSigWalletAbi, actionName, actionArgs) }; const ethereumTx = new EthereumTx(params); ethereumTx.sign(Buffer.from(privateKey.slice(2), "hex")); return ethereumTx.serialize().toString("hex"); } function encode(contractAbi, functionName, functionArgs) { for (const object of contractAbi) if (object.name == functionName) return web3.eth.abi.encodeFunctionCall(object, functionArgs); throw new Error("function " + functionName + " does not exist"); }
變數
web3
和MultiSigWalletAbi
假定為全域變數並已初始化。正如您從 中可以理解的那樣
value: 0
,上面的程式碼僅支持不傳遞乙太的函式,但可以通過傳遞很容易地啟用value
輸入。從 中可以理解
chainId: 1
,上面的程式碼僅支持部署在主網上的合約,但可以通過chainId
輸入輕鬆啟用。