Solidity
Solidity如何檢查使用者是否已經使用了另一個契約?
我試圖弄清楚如何在契約之間建立簡單的通信。
例如,我們有一個合約 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");
希望能幫助到你。