Solidity

Solidity如何檢查使用者是否已經使用了另一個契約?

  • April 4, 2019

我試圖弄清楚如何在契約之間建立簡單的通信。

例如,我們有一個合約 Passport,使用者在其中寫入他的數據。之後,通過選舉合約,使用者投票。合約選舉應該檢查使用者是否有護照,然後才允許他投票。

這是我嘗試的方法:

護照契約

contract Passport
{
   struct      Person
   {
       string  name;
       string  surname;
       uint8   age;
       uint256 id;
       bool    registered;
   }

   address payable public              owner;
   mapping(address => Person) public   people;
   uint256                             idCount;

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

   constructor() public payable
   {
       owner = msg.sender;
   }

   function registerID(string memory _name, string memory _surname, uint8 _age) public
   {
       require(!people[msg.sender].registered);

       people[msg.sender].name = _name;
       people[msg.sender].surname = _surname;
       people[msg.sender].age = _age;
       people[msg.sender].id = idCount;

       people[msg.sender].registered = true;

       idCount += 1;
   }

   // I use this function to check is the user have passport
   function isRegistered(address _address) public view returns (bool)
   {
       return people[_address].registered;
   }

   function end() ownerOnly public
   {
       selfdestruct(owner);
   }
}

選舉契約

contract Election
{
   struct      Candidate
   {
       string  name;
       uint    voteCount;
   }

   struct      Voter
   {
       bool    authorized;
       bool    voted;
       uint    voteTarget;
   }
   address payable  public             owner;
   string public                       electionName;
   mapping(address => Voter) public    voters;
   Candidate[] public                  candidates;
   uint public                         totalVotes;
   Passport                            pass;

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

   constructor(string memory _electionName) public
   {
       owner = msg.sender;
       electionName = _electionName;
   }

   function addCandidate(string memory _candidateName) ownerOnly public
   {
       candidates.push(Candidate(_candidateName, 0));
   }

   function getNumCandidate() public view returns(uint)
   {
       return candidates.length;
   }

   function authorize(address _person) public
   {
       voters[_person].authorized = true;
   }

   function vote(uint _voteIndex) public
   {
       // Here I register pasport with current user address
       pass = Pasport(msg.sender);

       // Here I check if the user already have pasport
       require(pass.isRegistered(msg.sender));

       require(!voters[msg.sender].voted);
       require(voters[msg.sender].authorized);

       voters[msg.sender].voteTarget = _voteIndex;
       voters[msg.sender].voted = true;

       candidates[_voteIndex].voteCount += 1;
       totalVotes += 1;
   }

   function end() ownerOnly public
   {
       selfdestruct(owner);
   }
}

檢查使用者是否已經使用另一個契約的正確方法是什麼?因為我的總是假的。而且我找不到正確的方法。

在較高層次上,您的Election契約需要了解 ABI 和Passport契約的位置。這是一個極簡主義的設置。

界面:

interface PassportInterface {
 // interface can't use `public`, so change to `external`.
 function isRegistered(address _address) external view returns(bool);
}

Election.

contract Election {
 // state var
 PassportInterface passportContract; // type var; as with uint x; or address a;
 // carry on
}

實例化它。獲取地址的常用方法是將其傳遞給建構子。

constructor(string memory _electionName, address passportContractAddress) public ... 
 passportContract = PassportInterface(passportContractAddress);
 // carry on
}

用它。

require(passportContract.isRegistered(msg.sender), "You don't have a passport");

希望能幫助到你。

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