在 NodeJs 中调用我的合同方法时执行恢复
Execution reverted when calling a method of my contract in NodeJs
我正在尝试在 Solidity 中创建自己的令牌,并使用 Web3 将令牌从一个帐户转移到另一个帐户 NodeJS/ExpressJS
.
我一直在使用 Infura
和 rinkeby
。
我可以调用我的方法balanceOf
,但我不能调用transferFrom
错误:
Returned error: execution reverted
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 中的代码 here。
我苦苦挣扎了好几天,一点进展都没有。看不出问题出在哪里。
我的目标是在 NodeJS 中将令牌从一个帐户转移到另一个帐户。
第106行抛出异常,因为不满足这个条件:_value <= allowance[_from][msg.sender]
您需要在调用 transferFrom()
函数之前设置 allowance
,很可能是通过调用 approve()
函数。
或者如果您想要简单的转账(不使用津贴),请改用 transfer()
功能。
此外,call()
用于读取 pure/view 函数的输出。要与 external/public 函数交互(发送以太坊交易),请使用 .send({from: <senderAddress>})
.
示例来自 https://web3js.readthedocs.io/en/v1.3.4/web3-eth-contract.html#web3-eth-contract
contract.methods.somFunc().send({from: ....})
我正在尝试在 Solidity 中创建自己的令牌,并使用 Web3 将令牌从一个帐户转移到另一个帐户 NodeJS/ExpressJS
.
我一直在使用 Infura
和 rinkeby
。
我可以调用我的方法balanceOf
,但我不能调用transferFrom
错误:
Returned error: execution reverted
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 中的代码 here。
我苦苦挣扎了好几天,一点进展都没有。看不出问题出在哪里。
我的目标是在 NodeJS 中将令牌从一个帐户转移到另一个帐户。
第106行抛出异常,因为不满足这个条件:_value <= allowance[_from][msg.sender]
您需要在调用 transferFrom()
函数之前设置 allowance
,很可能是通过调用 approve()
函数。
或者如果您想要简单的转账(不使用津贴),请改用 transfer()
功能。
此外,call()
用于读取 pure/view 函数的输出。要与 external/public 函数交互(发送以太坊交易),请使用 .send({from: <senderAddress>})
.
示例来自 https://web3js.readthedocs.io/en/v1.3.4/web3-eth-contract.html#web3-eth-contract
contract.methods.somFunc().send({from: ....})