如何使用 MetaMask API 发送一些自定义令牌?
How to send some custom tokens with MetaMask API?
MetaMask 文档页面上的示例代码似乎只发送 ETH。我应该如何自定义示例代码以发送一些自定义令牌?
const transactionParameters = {
nonce: '0x00', // ignored by MetaMask
gasPrice: '0x09184e72a000', // customizable by user during MetaMask confirmation.
gas: '0x2710', // customizable by user during MetaMask confirmation.
to: '0x0000000000000000000000000000000000000000', // Required except during contract publications.
from: ethereum.selectedAddress, // must match user's active address.
value: '0x00', // Only required to send ether to the recipient from the initiating external account.
data:
'0x7f7465737432000000000000000000000000000000000000000000000000000000600057', // Optional, but used for defining smart contract creation and interaction.
chainId: '0x3', // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.
};
// txHash is a hex string
// As with any RPC call, it may throw an error
const txHash = await ethereum.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
发送 ERC-20 代币的交易需要将代币合约作为接收者(to
字段),并且 data
字段包含执行其 transfer()
函数以及令牌接收者的地址和数量。
const transactionParameters = {
from: accounts[0],
to: tokenContractAddress,
data: getDataFieldValue(tokenRecipientAddress, tokenAmount),
};
await ethereum.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
您可以使用例如 web3js 库 (docs) 对 data
字段值进行编码。 transfer()
函数是标准化的——所以假设代币合约遵循标准,它对任何代币合约都是一样的。
function getDataFieldValue(tokenRecipientAddress, tokenAmount) {
const web3 = new Web3();
const TRANSFER_FUNCTION_ABI = {"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"};
return web3.eth.abi.encodeFunctionCall(TRANSFER_FUNCTION_ABI, [
tokenRecipientAddress,
tokenAmount
]);
}
对于使用 encodeABI 函数的 Petr 解决方案的更简洁版本。
await window.ethereum
.request({
method: "eth_sendTransaction",
params: [
{
from: accounts[0],
to: TOKEN_CONTRACT_ADDRESS,
data: tokenContract.methods
.transfer(receiverAddress, amount)
.encodeABI(),
},
],
})
.then((result) => console.log(result))
.catch((error) => console.error(error));
MetaMask 文档页面上的示例代码似乎只发送 ETH。我应该如何自定义示例代码以发送一些自定义令牌?
const transactionParameters = {
nonce: '0x00', // ignored by MetaMask
gasPrice: '0x09184e72a000', // customizable by user during MetaMask confirmation.
gas: '0x2710', // customizable by user during MetaMask confirmation.
to: '0x0000000000000000000000000000000000000000', // Required except during contract publications.
from: ethereum.selectedAddress, // must match user's active address.
value: '0x00', // Only required to send ether to the recipient from the initiating external account.
data:
'0x7f7465737432000000000000000000000000000000000000000000000000000000600057', // Optional, but used for defining smart contract creation and interaction.
chainId: '0x3', // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.
};
// txHash is a hex string
// As with any RPC call, it may throw an error
const txHash = await ethereum.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
发送 ERC-20 代币的交易需要将代币合约作为接收者(to
字段),并且 data
字段包含执行其 transfer()
函数以及令牌接收者的地址和数量。
const transactionParameters = {
from: accounts[0],
to: tokenContractAddress,
data: getDataFieldValue(tokenRecipientAddress, tokenAmount),
};
await ethereum.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
});
您可以使用例如 web3js 库 (docs) 对 data
字段值进行编码。 transfer()
函数是标准化的——所以假设代币合约遵循标准,它对任何代币合约都是一样的。
function getDataFieldValue(tokenRecipientAddress, tokenAmount) {
const web3 = new Web3();
const TRANSFER_FUNCTION_ABI = {"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"};
return web3.eth.abi.encodeFunctionCall(TRANSFER_FUNCTION_ABI, [
tokenRecipientAddress,
tokenAmount
]);
}
对于使用 encodeABI 函数的 Petr 解决方案的更简洁版本。
await window.ethereum
.request({
method: "eth_sendTransaction",
params: [
{
from: accounts[0],
to: TOKEN_CONTRACT_ADDRESS,
data: tokenContract.methods
.transfer(receiverAddress, amount)
.encodeABI(),
},
],
})
.then((result) => console.log(result))
.catch((error) => console.error(error));