Javascript

訪問映射中的所有元素

  • August 16, 2018

我是新手。我正在嘗試訪問申請人結構中的所有元素。在我的捐贈功能中,如果捐贈者未指定要捐贈的組織,則金額將分配給申請人內的所有組織。我在網上查看過,由於 gas 成本高,迭代映射顯然是個壞主意。那我還能怎樣實現我的目標呢?

   pragma solidity ^0.4.2;

contract DonationContract
{
   address owner;

   struct Applicant
   {
       address Org;
       string Name;
       string OrgType;
       string Number;
       string Email;
       uint256 Wallet;
       uint256 DonationFunds;
       bool approved;
   }

   constructor() public 
   {
       owner = msg.sender;
       facilitators[msg.sender] = true;
   }

   mapping (address => Applicant) public applicants;

   mapping(address => bool) facilitators;

   modifier Owner() 
   {
       require(msg.sender == owner);
       _;
   }

   modifier OnlyFacilitator()
   {
       require(facilitators[msg.sender] == true);
       _;
   }

    modifier Approved(address Org) 
   {
       require(applicants[Org].approved == true);
       _;
   }

   function approve(address Org) OnlyFacilitator public
   {
       applicants[Org].approved = true;
   }

     function Donate(uint256 amount, address Org) Approved(Org)  public
   {
       if(Org==0)
       {
           //Split donation amount amongst all applicants donationfunds
       }
       else
       applicants[Org].DonationFunds += amount;

       if(applicants[Org].DonationFunds >= 10000)
       {
           applicants[Org].DonationFunds -=10000;
           applicants[Org].Wallet += 10000;
       }
   }

    function addFacilitator(address _addr) Owner public
   {
       facilitators[_addr] = true;
   }
}

除非您將每個值的鍵儲存在某處,否則您無法遍歷映射。

以下是您可以執行此操作的兩種方法。兩者都有自己的問題。

  1. (首選/去中心化方式)創建一個功能,允許組織claim在契約中進行捐贈。這可以通過一個簡單的 Web 界面讓他們使用變得更容易。該功能將簡單地檢查使用者是否在合約中儲存了資金,並允許他們提取適當的金額。以下是一個我沒有測試過的例子,但應該給你適當的指導。注意:如果組織是自由添加/刪除的,這不起作用,而是存在已知數量的組織並且這不會改變。這只是一般指南,必鬚根據您嘗試實現的特定邏輯進行修改。應該有檢查/要求/等。我沒有包括在內。
uint256 public numOfOrgs;   // Number of orgs able to claim
uint256 public claimIndex;  // Count of claimable donations
mapping(uint256 => uint256) public claimAmount // The claimable amount per index
mapping(address => mapping(uint256 => bool)) public isIndexClaimed; // Amount of ETH each org can claim per claimable event


function donate()
{
   // Donation logic where donator does not specify
   if donatorDidNotSpecify {
       addIndex(donationAmount)
   }
}

function addIndex(uint256 _donationAmount)
   internal
{
   uint256 amountPerOrg = _donationAmount.div(numOfOrgs);
   claimAmount[claimIndex] = amountPerOrg;
   claimIndex += 1;           
}

function claim(uint256 _claimIndex)
   public
{
   if (isIndexClaimed[msg.sender][_claimIndex] == false) {
       isIndexClaimed[msg.sender][_claimIndex] = true;  // Org cannot claim multiple times per index
       uint256 amount = claimAmount[_claimIndex];
       msg.sender.transfer(amount);
   }
}
  1. 將地址數據庫(映射的密鑰)保存在鏈下,並執行一個腳本,在捐贈者未指定接收者的情況下將捐贈的內容分發給每個組織。正如您所提到的,隨著更多組織的加入,這將花費您一定數量的 gas。

引用自:https://ethereum.stackexchange.com/questions/56718