通過 Truffle 控制台訪問結構內的映射
這個問題在這裡被問到,但我想我會更清楚一點。是否可以通過下面程式碼中的 Truffle 控制台訪問
funders
映射(粗體)?這取自Solidity 文件:struct Funder { address addr; uint amount; } struct Campaign { address beneficiary; uint fundingGoal; uint numFunders; uint amount; mapping (uint => Funder) funders; } uint numCampaigns; mapping (uint => Campaign) campaigns; function newCampaign(address beneficiary, uint goal) returns (uint campaignID) { campaignID = numCampaigns++; // campaignID is return variable // Creates new struct and saves in storage. We leave out the mapping type. campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0); } function contribute(uint campaignID) payable { Campaign storage c = campaigns[campaignID]; // Creates a new temporary memory struct, initialised with the given values // and copies it over to storage. // Note that you can also use Funder(msg.sender, msg.value) to initialise. c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value}); c.amount += msg.value; }
在您執行
newCampaign
並向contribute
新創建的活動添加資金後,返回的對像如下:
[ '0x740bd112e4d310a69aae3cee9ca8e72d1b1f8a21', { [String: '15000'] s: 1, e: 4, c: [ 15000 ] }, { [String: '5'] s: 1, e: 0, c: [ 5 ] }, { [String: '16000'] s: 1, e: 4, c: [ 16000 ] }, { [String: '1504125631'] s: 1, e: 9, c: [ 1504125631 ] } ]
結構中的所有變數
Campaign
都是可見的,除了funders
變數。這funders
可能是因為沒有在儲存中初始化嗎?
如果你能原諒自我推銷,這個解釋器可能會揭示一種實現目標的方法:https ://medium.com/@robhitchens/enforcing-referential-integrity-in-ethereum-smart-contracts-a9ab1427ff42
編輯
主要思想如下。
這兩個實體的基本資料結構是結構的映射(用於隨機訪問)和作為動態數組的鍵的無序索引(便於計數和列舉)。此處的“帶索引的映射結構”標題下有一個範例。Solidity 是否有很好解決且簡單的儲存模式?
所以基本上,您只需為您的兩個實體與其中兩個建立契約。
接下來,加入。建議您在使用映射的地方嵌入一個動態的鍵數組。這樣就可以計算列表中的行數,還可以通過一次返回一個鍵來迭代列表。
大致:
struct CampaignStruct { ... address funders[]; bool exists; } mapping(bytes32 => CampaignStruct) public campaignStructs; bytes32[] public campaignIndex; struct FunderStruct { ... bool exists; } mapping(address => FunderStruct) public funderStructs; address[] public funderIndex; function getCampaignCount() public constant returns(uint count) { return campaignIndex.length; } function getFunderCount() public constant returns(uint count) { return funderIndex.length; } function getCampaignAtIndex(uint row) public constant returns(<details>) {} function getCampaignFunderCount(bytes32 campaignId) public constant returns(uint count) { return campaignStructs[campaignId].funders.length; } function getCampaignFunderAtIndex(bytes32 campaignId, uint row) public constant returns(address funder) { return campaignStructs[campaignId].funders[row]; }
如果您不需要刪除,則 upsert 樣式編寫器可以解決問題,因為您可以直接寫入映射。新的鍵被添加到索引中
.push()
。您可以使用 abool exists
來了解您是在更新還是插入。希望能幫助到你。
您無法檢索結構內部映射的鍵->值對列表,原因與您無法檢索結構外部映射的鍵值對的原因相同:合約不知道它們是什麼. 有關更詳細的解釋,請參閱此答案:我們可以將所有元素儲存在合約中的映射中嗎
假設您自己擁有密鑰,您可以創建自己的訪問器來檢索它,例如:
function campaign_funder(uint campaignID, uint funderID) constant returns (address) { return campaigns[campaignID].funders[funderID].addr; }
如果您需要能夠在不知道他們的 ID 的情況下檢索資助者列表,則必須儲存一些額外的數據,以便契約可以獲取 ID。有關詳細資訊,請參閱我連結的答案。