Solidity
返回一個結構並通過 Web3 讀取
我正在使用結構映射將數據儲存在我的契約中。
例如,假設我正在儲存由員工 ID 映射的員工資訊(姓名/地址/薪水)。
通過網路前端,我希望能夠指定一個員工 ID,並在我的契約中呼叫一個函式(使用 Web3.JS)來返回員工資訊。
如果返回結構,我如何訪問數據。那可能嗎?
概括
將結構的欄位作為單獨的返回變數返回。
**編輯:**截至 2021 年,可以直接返回結構。看到這個答案。
例子
我正在使用以下命令在本地開發區塊鏈中執行此程式碼:
geth --datadir ~/devdata --dev --nodiscover \ --mine --minerthreads 1 --port 30301 \ --maxpeers 0 --verbosity 3 --rpc console
您的 Web 前端應該能夠發送事務以插入使用者,並呼叫函式來獲取使用者數量和使用者資訊。
樣本契約
contract SalaryInfo { struct User { uint salaryId; string name; string userAddress; uint salary; } User[] public users; function addUser(uint _salaryId, string _name, string _userAddress, uint _salary) public returns(uint) { users.length++; users[users.length-1].salaryId = _salaryId; users[users.length-1].name = _name; users[users.length-1].userAddress = _userAddress; users[users.length-1].salary = _salary; return users.length; } function getUsersCount() public constant returns(uint) { return users.length; } function getUser(uint index) public constant returns(uint, string, string, uint) { return (users[index].salaryId, users[index].name, users[index].userAddress, users[index].salary); } }
扁平化原始碼
我使用
stripCrLf
方法(來自How to load Solidity source file into geth)將格式化的原始碼轉換為可以插入geth
控制台的單行。或者,搜尋將從程式碼中刪除換行符的網頁。然後將您的程式碼分配給 JavaScript 變數:> var salaryInfoSource='contract SalaryInfo { struct User { uint salaryId; string name; string userAddress; uint salary; } User[] public users; function addUser(uint _salaryId, string _name, string _userAddress, uint _salary) public returns(uint) { users.length++; users[users.length-1].salaryId = _salaryId; users[users.length-1].name = _name; users[users.length-1].userAddress = _userAddress; users[users.length-1].salary = _salary; return users.length; } function getUsersCount() public constant returns(uint) { return users.length; } function getUser(uint index) public constant returns(uint, string, string, uint) { return (users[index].salaryId, users[index].name, users[index].userAddress, users[index].salary); }}'
將合約插入區塊鏈
編譯程式碼:
> var salaryInfoCompiled = web3.eth.compile.solidity(salaryInfoSource);
將程式碼載入到區塊鏈中:
> var salaryInfoContract = web3.eth.contract(salaryInfoCompiled.SalaryInfo.info.abiDefinition); > var salaryInfo = salaryInfoContract.new({from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 1000000}, function(e, contract) { if (!e) { if(!contract.address) { console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); } else { console.log("Contract mined! Address: " + contract.address); console.log(contract); } } } )
等待以下消息表明合約已被探勘:
I0505 09:12:15.712867 27030 xeth.go:1026] Tx(0x7747500b881c8da44efbc3b5d1c2c762f1cd52d2dd74050edbfed10e51a29d8a) created: 0x0bb1d7a6b31f7a7e23e6d902bac0eb5f9c721c54 Contract transaction send: TransactionHash: 0x7747500b881c8da44efbc3b5d1c2c762f1cd52d2dd74050edbfed10e51a29d8a waiting to be mined... ... Contract mined! Address: 0x0bb1d7a6b31f7a7e23e6d902bac0eb5f9c721c54 [object Object]
插入使用者
在這裡,我們將 2 個使用者添加到合約中:
> salaryInfo.addUser(123, "User 123", "123 drive way, the uncentralised kingdom", 100, {from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 500000}); "0x7c22797d6b7717beb398a65159b1009fba3bbc9e4917ee1584bed60ea74eac11" > salaryInfo.addUser(234, "User 234", "234 drive way, the uncentralised kingdom", 200, {from:web3.eth.accounts[0], data: salaryInfoCompiled.SalaryInfo.code, gas: 500000}); "0xed197c9a6fbc70c19cc95bcdc6943e38736c080052e9e1a4f7562216d6de4c78"
檢索數據
讓我們獲取使用者數:
> var numberOfUsers = salaryInfo.getUsersCount(); undefined > numberOfUsers 2
讓我們獲取第一個使用者的資訊:
> salaryInfo.getUser(0) [123, "User 123", "123 drive way, the uncentralised kingdom", 100]
第二個使用者:
> var user2 = salaryInfo.getUser(1); undefined > user2 [234, "User 234", "234 drive way, the uncentralised kingdom", 200]