Contract-Deployment
錯誤:此合約對象尚未設置地址,請先設置地址
我應該點擊 HTML 中的按鈕,以便通過點擊必須部署智能合約並且必須執行其功能。但是當我在 Node-js 中編寫這兩個操作的程式碼時,會發生以下錯誤:
`Error: This contract object doesn't have address set yet, please set an address first.`
通過以下程式碼,我部署合約並執行其功能。合約的功能是
fill
。app.post('/send-data', function(q,r){ var source2='E:/Alireza/contracts/customer.sol'; var customercompiled=solc.compile(source2) var customerJson="E:/Alireza/build/contracts/customer.json"; var customerJs=JSON.parse(fs.readFileSync(customerJson)); var ByteCode="..."; var customer=new web3.eth.Contract(customerJs.abi, null, {data: ByteCode}); web3.eth.personal.unlockAccount("0x83Ad536099658519ee6A40A3faCAf3dDcEf6178a","Alireza").then(()=>{console.log("Address unlocked");}).catch(console.error); customer.deploy().send({from: "0x6Db320B080b956c371c4bC5b00eF74e73bCE7798", gas:2100000, gasPrice:200}).then((instance)=>{console.log("Contract mined at "+instance.options.address); customerInstance=instance}//Here, the contract is deployed. customer.methods.fill(Arg1,Arg2).send({from: "0x6Db320B080b956c371c4bC5b00eF74e73bCE7798", gas:2000000, gasPrice:200}); //Above line is to interact with the contract and run its function called "fill". );
如何消除上述錯誤並改進上述程式碼?
提供的程式碼中有兩個問題: 1-
customer.methods.fill(…).send(…)
與還沒有地址的實例互動,因為:var customer=new web3.eth.Contract(…);
定義一個尚未部署的合約,因此它沒有地址。因此,我們必須在部署合約後進行實例化。部署後,我們使用以下程式碼獲取一個實例:
var customerDeployed=new web3.eth.Contract(customerJs.abi,“address of the contract”);
instance.options.address
我們可以通過inside訪問地址.then(…)
。2- 與智能合約的互動必須在將其部署到網路後進行。在部署命令行之後編寫
customer.methods.fill(…)
並不能保證這些命令按照相同的順序執行,因為這兩個命令採用相同的實例。我們將互動程式碼寫入合約中,.then(…)
以確保在部署後執行。總而言之,實例化部署的合約和與之互動的命令應該用
.then(…)
.解決方案程式碼:
app.post('/send-data', function(q,r){ var source2='E:/Alireza/contracts/customer.sol'; var customercompiled=solc.compile(source2) var customerJson="E:/Alireza/build/contracts/customer.json"; var customerJs=JSON.parse(fs.readFileSync(customerJson)); var ByteCode="..."; var customer=new web3.eth.Contract(customerJs.abi, null, {data: ByteCode}); web3.eth.personal.unlockAccount("0x83Ad536099658519ee6A40A3faCAf3dDcEf6178a","Alireza").then(()=>{console.log("Address unlocked");}).catch(console.error); customer.deploy().send({from: "0x6Db320B080b956c371c4bC5b00eF74e73bCE7798", gas:2100000, gasPrice:200}).then((instance)=>{console.log("Contract mined at "+instance.options.address); customerInstance=instance; var deployedCustomer=new web3.eth.Contract(customer_abi, instance.options.address) ;deployedCustomer.methods.fill(q.body.firstname, q.body.lastname, q.body.id1, q.body.KYC, q.body.Level, q.body.hashValue, "BankA").send({from: "0xF25e4413a9bB7cEf81239Ab5eD2352Da472330b8", gas:3000000, gasPrice:200}); });
我猜您認為以下幾行定義了契約;
var customer=new web3.eth.Contract(customerJs.abi, null, {data: ByteCode}); web3.eth.personal.unlockAccount("0x83Ad536099658519ee6A40A3faCAf3dDcEf6178a","Alireza").then(()=>{console.log("Address unlocked");}).catch(console.error); customer.deploy().send({from: "0x6Db320B080b956c371c4bC5b00eF74e73bCE7798", gas:2100000, gasPrice:200}).then((instance)=>{console.log("Contract mined at "+instance.options.address); customerInstance=instance}
但是,這只是部署一個合約。要執行合約的功能,您需要將該合約定義為已部署的合約。通過問題中的程式碼,您正在呼叫平台中的合約,但
web3.js
無法理解它在哪裡。你應該理解web3.js
這一點。在你部署了合約並且它有一個乙太坊地址之後,你應該使用這個命令:let Customer=new web3.eth.Contract(customer_abi, <address>);
現在,
web3.js
可以找到合約,然後通過以下方式執行給定的函式:Customer.methods.fill(arg1, arg2, arg3, arg4, arg5, arg6, arg7).send({from:<address>, gas:<value>, gasPrice:<value>});
正如@Alireza 所提到的:“必須在將智能合約部署到網路之後進行互動”並使用
.then()
保證。所以,你應該把答案的程式碼放在一個.then()
. 因此,我們有以下問題,而不是問題提供的內容:let customer=new web3.eth.Contract(customerJs.abi, null, {data: ByteCode}); web3.eth.personal.unlockAccount(<address>,<string>).then(()=>{console.log("Address unlocked");}).catch(console.error); customer.deploy().send({from:<address>, gas:<value>, gasPrice:<value>}).then((instance)=>{console.log("Contract mined at "+instance.options.address); customerInstance=instance; let Customer=new web3.eth.Contract(customer_abi, instance.options.address) ; Customer.methods.fill(arg1, q.body.lastname,..., arg7).send({from:<address>, gas:<value>, gasPrice:<value>});