Solidity

如何使用元遮罩和 web3 發送簽名交易?

  • August 29, 2021

我一直堅持將簽署的交易發送到部署在 Ropsten 網路上的智能合約。

作為學習目的,我創建了一個“投票”智能合約。這份契約包括我們可以投票的 2 名候選人。一個使用者只能簽名一次。該合約已在 Ropsten 上部署和測試。如果我只使用 Web3(即我手動提供我的私鑰),它會很好用。

現在,我希望使用者表明自己的身份,然後在投票上簽名。我在這里卡住了。

使用 Vue,我有 2 個主要方法:

方法 1:啟用元遮罩

this.provider = await detectEthereumProvider();

   if (this.provider) {

     const accounts = await this.provider.request(
        {
             method: 'eth_requestAccounts'
         }
     );

     this.account = accounts[0];

   } else {

     console.log('Please install MetaMask!');

   }

方法2:發送簽名投票(這裡我卡住了)–>部分程式碼

 const ropsten = 'https://ropsten.infura.io/v3/MY_KEY';

 const web3 = new Web3(ropsten);

 const contract = new web3.eth.Contract(
                       Election.abi, 
                       this.params.to
                       );
 [??????????????]

 try {

   const txHash = await this.provider.request({
     method: 'eth_sendTransaction',
     params: [
       {
         from: this.account,
         to: this.contractAddress,
         data: ??????????????
       }
     ],
   });

   console.log(txHash);

 } catch (error) {

   console.log(error);
   
 }
}

如果我理解得很好,現在我必須創建我的函式的十六進制數據參數來投票。

這是我將使用的投票功能

const vote = await contract.methods.vote(1).send({
              from: ...
              to: ...
              });

在這裡我迷路了,我不知道如何正確進行。

預期輸出:

  • 首先,使用者啟用 Metamask,
  • 二、使用投票給候選人1或2
  • 在將交易發送到 Ropsten 之前,Metamask 請求對交易進行簽名

有關資訊,請參閱我的 Election.sol 智能合約:

pragma solidity >=0.4.21 <0.7.0;

contract Election {

   //Model Candidate
   struct Candidate {
       uint id;
       string name;
       uint voteCount;
   }

   mapping(uint => Candidate) public candidates;
   //store accounts that have voted
   mapping(address => bool) public voters;

   uint public candidatesCount;

   event votedEvent (
       uint indexed _candidateId
   );

   constructor() public {
       addCandidate("Barack Obama");
       addCandidate("Donald Trump");
   }

   function addCandidate(string memory _name) private {
       candidatesCount ++;
       candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
   }

   function vote(uint _candidateId) public {
       //not voted yet
       require(!voters[msg.sender]);

       //valid vandidate
       require(_candidateId > 0 && _candidateId <= candidatesCount);

       //record vote
       voters[msg.sender] = true;

       //update candidate vote count
       candidates[_candidateId].voteCount ++;

       //voted event
       emit votedEvent(_candidateId);
   }

}

歡迎您的幫助!提前致謝!

由於您創建了一個合約實例,您可以使用它對交易進行 Metamask 格式化並向使用者發送簽名請求。

嘗試替換這個:

const txHash = await this.provider.request({
 method: 'eth_sendTransaction',
 params: [
   {
     from: this.account,
     to: this.contractAddress,
     data: ??????????????
   }
 ],
})

有了這個:

contract.methods.vote(1).send({
          from: accounts[0]
          
          });

您應該會看到一個 Metamask 請求來簽署 Tx。

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