Solidity
大量數據的設置和獲取
我創建了一個在區塊鏈中插入一個數字(uint)的合約,但我如何檢索所有插入的數字?
這是我的 html,我在區塊鏈中放了 1 個數字,我只會看到最後插入的數字:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script> </head> <body> <script> window.onload = function () { // check to see if user has metamask addon installed on his browser. check to make sure web3 is defined if (typeof web3 === 'undefined') { document.getElementById('metamask').innerHTML = 'You need <a href="https://metamask.io/">MetaMask</a> browser plugin to run this example' } // call the getvalue function here getvalue(); } //function to retrieve the last inserted value on the blockchain function getvalue() { try { // contract Abi defines all the variables,constants and functions of the smart contract. replace with your own abi var abi = [] //contract address. please change the address to your own var contractaddress = ''; //instantiate and connect to contract address via Abi var myAbi = web3.eth.contract(abi); var myfunction = myAbi.at(contractaddress); //call the get function of our SimpleStorage contract myfunction.get.call(function (err, xname) { if (err) { console.log(err) } if (xname) { //display value on the webpage document.getElementById("xbalance").innerHTML = "primo: " + xname; } }); } catch (err) { document.getElementById("xbalance").innerHTML = err; } } function setvalue() { try { // contract Abi defines all the variables,constants and functions of the smart contract. replace with your own abi var abi = [] //contract address. please change the address to your own var contractaddress = ''; //instantiate and connect to contract address via Abi var myAbi = web3.eth.contract(abi); var myFunction= myAbi.at(contractaddress); //call the set function of our SimpleStorage contract myFunction.set.sendTransaction(document.getElementById("xvalue").value, { from: web3.eth.accounts[0], gas: 4000000 }, function (error, result) { if (!error) { console.log(result); } else { console.log(error); } }) } catch (err) { document.getElementById("xvalue").innerHTML = err; } } </script> <center> <div id="metamask" class="container"></div> <h3>Inserimento dati nella Blockchain Ethereum</h3> <br /> <table class="table"> <div id="xbalance" class="container"></div> <thead> <tr> <th scope="col">Inserisci token: </th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td><input id="xvalue" type="text" class="form-control" /></td> </tr> <tr> <td><input id="Button1" type="button" class="btn btn-primary" onclick="setvalue()" value="Add to Blockchain" /></td> </tr> </tbody> </table> </center> </body> </html>
我的契約是:
pragma solidity ^0.4.24; contract M { uint256 storeddata; function set(uint256 x) public { storeddata = x; } function get() public view returns(uint256) { return storeddata; } }
Rob 的回答很好。如果您出於某種原因不想使用事件,您可以:
- 將您的號碼添加到 uint 數組
- 增加一個
counter
然後,如果您想檢索所有數字,您將使用
counter
作為您的索引來遍歷數組。
在下面的範例中,有一個動態數組,
numbers
並且該appendNumber()
函式只是不斷添加到列表中。合約會為我強烈推薦的每個重要狀態更改發出一個事件。軟體客戶端可以通過多種方式觀察和檢查。
- 訂閱/觀看事件日誌。這有助於建構狀態的離線表示,因為沒有相應的事件就不會發生任何事情。客戶端將始終知道陣列的真實狀態而無需詢問。
- 檢查
numbers()
功能。它接受一個參數index
並返回一個數字。對索引的迭代是客戶端的關注點。我經常添加一個輔助函式來返回數組長度來幫助解決這個問題。為簡潔起見省略,看起來像function getCount() public view returns(uint count) { return numbers.length; }
- 可以添加一個函式來返回一個數字數組。通常不建議這樣做,因為氣體成本(處理)隨著規模的增加而增加。這甚至會使超出特定數組大小的使用變得不可能。通常,這不是必需的,因為上面的兩個替代方案已經解決了這個問題。
pragma solidity 0.5.1; contract SetGet { uint[] public numbers; event LogNewNumber(address setter, uint number); function appendNumber(uint value) public { numbers.push(value); emit LogNewNumber(msg.sender, value); } }
希望能幫助到你。