我正在尝试在Solidity中制作自己的令牌,并使用Web3将令牌从一个帐户转移到另一个帐户NodeJS/ExpressJS。
我一直在Infura使用rinkeby.
我可以调用我的方法balanceOf,但我不能调用transferFrom
错误:
返回错误:执行恢复
const express = require('express');
const app = express();
const web3 = require('web3');
const INFURA_BASE_URL = 'https://rinkeby.infura.io/v3/';
const INFURA_API_KEY = '........';
web3js = new web3(new web3.providers.HttpProvider(INFURA_BASE_URL + INFURA_API_KEY));
/*
Sender & Receiver keys
*/
const SENDER_PUBLIC_KEY = '........';
const SENDER_PRIVATE_KEY = '.......';
const RECEIVER_PUBLIC_KEY = '......';
/*
Contract ABI.
*/
const CONTRACT_ABI = [
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_value",
"type": "uint256"
}
],
"name": "burn",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "burnFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_extraData",
"type": "bytes"
}
],
"name": "approveAndCall",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "initialSupply",
"type": "uint256"
},
{
"name": "tokenName",
"type": "string"
},
{
"name": "tokenSymbol",
"type": "string"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Burn",
"type": "event"
}
];
const CONTRACT_ABI_ADDRESS = '............';
/*
A controller listening at: http://localhost:3000/send
*/
app.get('/send', async function (req, apiResponse) {
// Creating contract object
const contract = new web3js.eth.Contract(CONTRACT_ABI, CONTRACT_ABI_ADDRESS, {from: SENDER_PUBLIC_KEY});
// Check the balance (working good)
await contract.methods.balanceOf(RECEIVER_PUBLIC_KEY)
.call()
.then(res => {
const str = web3.utils.fromWei(res);
console.log('balance: ', str);
})
.catch(err => {
console.log(err);
});
// Set the allowance (working)
await contract.methods.approve(SENDER_PUBLIC_KEY, 1)
.call()
.then(res => {
console.log('approve: ', res);
})
.catch(err => {
console.log('Error [approve]', err);
});
// Initiate a transfer (not working)
await contract.methods.transferFrom(SENDER_PUBLIC_KEY, RECEIVER_PUBLIC_KEY, 1)
.call()
.then(res => {
console.log('transferFrom: ', res);
})
.catch(err => {
console.log('Error [transferFrom]', err);
});
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000`)
})
我在 Solidity 中的代码在这里。
我已经挣扎了好几天没有任何进展。看不出问题出在哪里。
我的目标是在 NodeJS 中将令牌从一个帐户转移到另一个帐户。