Javascript 使用 web3 以太坊调用智能合约方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48184969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
calling smart contracts methods using web3 ethereum
提问by SKYnine
Trying to work around the blockchain using Ethereum, I'm facing problems when trying to interface with a deployed contract. What I would try to achieve is to call a method to display information added to a private blockchain deployed locally using Geth.
尝试使用以太坊解决区块链问题,我在尝试与已部署的合约交互时遇到了问题。我将尝试实现的是调用一种方法来显示添加到使用 Geth 在本地部署的私有区块链中的信息。
I can't call any function from my smart contract and I've been wondering if I'm doing something wrong... Could someone tell me how to achieve a simple call to one of the method from this contract? let say display the existing agencies, or the agency name from which the user is part of.
我无法从我的智能合约中调用任何函数,我一直在想我是否做错了什么......有人能告诉我如何实现对这个合约中的一种方法的简单调用吗?假设显示现有机构,或用户所属的机构名称。
My contract: agency.sol
我的合同:agency.sol
pragma solidity ^0.4.18;
// We have to specify what version of compiler this code will compile with
contract Agency {
event NewAgency(uint agencyId, string name, uint dna);
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
//agency structure
struct Agency {
string name;
uint dna;
}
Agency[] public agencies;
mapping (uint => address) public agencyToOwner;
mapping (address => uint) ownerAgencyCount;
function _createAgency(string _name, uint _dna) private {
uint id = agencies.push(Agency(_name, _dna)) - 1;
agencyToOwner[id] = msg.sender;
ownerAgencyCount[msg.sender]++;
NewAgency(id, _name, _dna);
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}
function createRandomAgency(string _name) public {
//make sure contract can only execute if user is not part of an agency
require(ownerAgencyCount[msg.sender] == 0);
uint randDna = _generateRandomDna(_name);
_createAgency(_name, randDna);
}
}
the abiDefinition
abiDefinition
> abiDefinition
[ { constant: true,
inputs: [ [Object] ],
name: 'agencies',
outputs: [ [Object], [Object] ],
payable: false,
stateMutability: 'view',
type: 'function' },
{ constant: true,
inputs: [ [Object] ],
name: 'agencyToOwner',
outputs: [ [Object] ],
payable: false,
stateMutability: 'view',
type: 'function' },
{ constant: false,
inputs: [ [Object] ],
name: 'createRandomAgency',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function' },
{ anonymous: false,
inputs: [ [Object], [Object], [Object] ],
name: 'NewAgency',
type: 'event' } ]
Successfully deployed:
部署成功:
INFO [01-09|19:09:14] Submitted contract creation fullhash=0x7c43e896329138a6778938ca30d2f5f17f9a63062b359a4fccbd1a1be439f385 contract=0x65175d22C56E1Bad976A331A8B6B448cd4B3995d
and finally contractInstance:
最后contractInstance:
> contractInstance = AgencyContract.at(0x65175d22C56E1Bad976A331A8B6B448cd4B3995d)
Contract {
_eth:
Eth {
_requestManager: RequestManager { provider: [Object], polls: {}, timeout: null },
getBalance: { [Function: send] request: [Function: bound ], call: 'eth_getBalance' },
getStorageAt: { [Function: send] request: [Function: bound ], call: 'eth_getStorageAt' },
getCode: { [Function: send] request: [Function: bound ], call: 'eth_getCode' },
getBlock: { [Function: send] request: [Function: bound ], call: [Function: blockCall] },
getUncle: { [Function: send] request: [Function: bound ], call: [Function: uncleCall] },
getCompilers: { [Function: send] request: [Function: bound ], call: 'eth_getCompilers' },
getBlockTransactionCount:
{ [Function: send]
request: [Function: bound ],
call: [Function: getBlockTransactionCountCall] },
getBlockUncleCount:
{ [Function: send]
request: [Function: bound ],
call: [Function: uncleCountCall] },
getTransaction:
{ [Function: send]
request: [Function: bound ],
call: 'eth_getTransactionByHash' },
getTransactionFromBlock:
{ [Function: send]
request: [Function: bound ],
call: [Function: transactionFromBlockCall] },
getTransactionReceipt:
{ [Function: send]
request: [Function: bound ],
call: 'eth_getTransactionReceipt' },
getTransactionCount: { [Function: send] request: [Function: bound ], call: 'eth_getTransactionCount' },
call: { [Function: send] request: [Function: bound ], call: 'eth_call' },
estimateGas: { [Function: send] request: [Function: bound ], call: 'eth_estimateGas' },
sendRawTransaction: { [Function: send] request: [Function: bound ], call: 'eth_sendRawTransaction' },
signTransaction: { [Function: send] request: [Function: bound ], call: 'eth_signTransaction' },
sendTransaction: { [Function: send] request: [Function: bound ], call: 'eth_sendTransaction' },
sign: { [Function: send] request: [Function: bound ], call: 'eth_sign' },
compile: { solidity: [Object], lll: [Object], serpent: [Object] },
submitWork: { [Function: send] request: [Function: bound ], call: 'eth_submitWork' },
getWork: { [Function: send] request: [Function: bound ], call: 'eth_getWork' },
coinbase: [Getter],
getCoinbase: { [Function: get] request: [Function: bound ] },
mining: [Getter],
getMining: { [Function: get] request: [Function: bound ] },
hashrate: [Getter],
getHashrate: { [Function: get] request: [Function: bound ] },
syncing: [Getter],
getSyncing: { [Function: get] request: [Function: bound ] },
gasPrice: [Getter],
getGasPrice: { [Function: get] request: [Function: bound ] },
accounts: [Getter],
getAccounts: { [Function: get] request: [Function: bound ] },
blockNumber: [Getter],
getBlockNumber: { [Function: get] request: [Function: bound ] },
protocolVersion: [Getter],
getProtocolVersion: { [Function: get] request: [Function: bound ] },
iban:
{ [Function: Iban]
fromAddress: [Function],
fromBban: [Function],
createIndirect: [Function],
isValid: [Function] },
sendIBANTransaction: [Function: bound transfer] },
transactionHash: null,
address: 5.771290982673958e+47,
abi:
[ { constant: true,
inputs: [Array],
name: 'agencies',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function' },
{ constant: true,
inputs: [Array],
name: 'agencyToOwner',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function' },
{ constant: false,
inputs: [Array],
name: 'createRandomAgency',
outputs: [],
payable: false,
stateMutability: 'nonpayable',
type: 'function' },
{ anonymous: false,
inputs: [Array],
name: 'NewAgency',
type: 'event' } ],
agencies:
{ [Function: bound ]
request: [Function: bound ],
call: [Function: bound ],
sendTransaction: [Function: bound ],
estimateGas: [Function: bound ],
getData: [Function: bound ],
uint256: [Circular] },
agencyToOwner:
{ [Function: bound ]
request: [Function: bound ],
call: [Function: bound ],
sendTransaction: [Function: bound ],
estimateGas: [Function: bound ],
getData: [Function: bound ],
uint256: [Circular] },
createRandomAgency:
{ [Function: bound ]
request: [Function: bound ],
call: [Function: bound ],
sendTransaction: [Function: bound ],
estimateGas: [Function: bound ],
getData: [Function: bound ],
string: [Circular] },
allEvents: [Function: bound ],
NewAgency: { [Function: bound ] 'uint256,string,uint256': [Function: bound ] } }
I've tried:
我试过了:
contractInstance.agencies()
contractInstance.agencies.call()
contractInstance.agencies.call({from:ak})
results in Error: Invalid number of arguments to Solidity function
结果是 Error: Invalid number of arguments to Solidity function
contractInstance.agencies.call("name" {from:ak})
results in Error: invalid addressI also tried calling agencyToOwnerand createRandomAgencybut nothing works.
结果Error: invalid address我也试过打电话agencyToOwner,createRandomAgency但没有任何效果。
Any help would be gladly received! Thanks,
任何帮助都会很高兴收到!谢谢,
回答by Adam Kipnis
You can call contract functions by either using contract.methodName.call(), contract.methodName.sendTransaction(), or contract.methodName()methods. The last version simply delegates to one of the first two depending on the method type (ie, if it's a constant). See the Contract Methodssection in the docs.
您可以通过使用调用函数的合同contract.methodName.call(),contract.methodName.sendTransaction()或contract.methodName()方法。最后一个版本只是根据方法类型(即,如果它是 a constant)委托给前两个之一。请参阅文档中的合同方法部分。
The parameter list starts with the parameters for the function itself (if any), followed by an optional transaction object, followed by the callback. To call your createRandomAgency()method, you would do this:
参数列表以函数本身的参数(如果有)开始,然后是可选的事务对象,然后是回调。要调用您的createRandomAgency()方法,您可以这样做:
const contract = web3.eth.contract(contractAbi);
const contractInstance = contract.at(contractAddress);
const transactionObject = {
from: fromAccount,
gas: gasLimit
gasPrice: gasPriceInWei
};
contractInstance.createRandomAgency.sendTransaction('name', transactionObject, (error, result) => { // do something with error checking/result here });
The list of available options for the transaction object can be found here.
可以在此处找到交易对象的可用选项列表。
To call your public agenciesarray, it would look like
要调用您的公共agencies数组,它看起来像
contractInstance.agencies.call(0, (error, result) => {
if (!error) {
console.log(result.name);
console.log(result.dna);
}
}); // transaction object not needed
回答by sameepsi
I think you should try something like this-:
我认为你应该尝试这样的事情-:
var contractAbi= "" //here put your contract abi in json string
var deployedContract = web3.eth.contract(abi).at("contract address");
//now you should be able to access contract methods
deployedContract.agencies.call({from:address}, function(err,data){
console.log(data);
});
Test this out once.
测试一次。
回答by Filip
Try using callbacks or promises. The following code worked for me, when I wanted to get the return value from one of my contract's methods:
尝试使用回调或承诺。当我想从我的合同方法之一获取返回值时,以下代码对我有用:
const contract = web3.eth.contract(contractABI);
const contractInstance = contract.at(this.contractAddress);
return new Promise((resolve, reject) => {
contractInstance.**yourMethod**.call(function (error, result) {
if (error) {
console.log(error);
} else {
resolve(result);
}
});
}) as Promise<number>;
Also check out: https://github.com/ethereum/wiki/wiki/JavaScript-API#using-callbacks
另请查看:https: //github.com/ethereum/wiki/wiki/JavaScript-API#using-callbacks

