【问题标题】:Using the counter as ID - is it a good idea in a smart contract?使用计数器作为 ID - 在智能合约中是个好主意吗?
【发布时间】:2022-12-10 06:14:41
【问题描述】:

我编写了以下代码来跟踪智能合约中的存款。 我需要能够在未来的功能中引用个人存款。

pragma solidity ^0.8.4;

contract DepositsWithIds {
    address owner;

    struct Deposit {
        uint256 depositAmount;
        address depositor;
        uint256 counter;
    }

    constructor() payable {
    owner = msg.sender;
    }
  
    Deposit[] public activeDeposits;

    event DepositMade(address, uint256, uint256);

    function deposit() public payable returns (uint256 counter) {

        return ++counter;

        Deposit memory newDeposit = Deposit(

        msg.value,
        msg.sender,
        counter
    );

    activeDeposits.push(newDeposit);

    emit DepositMade(msg.sender, msg.value, counter);

    }
}

使用柜台作为唯一的存款 ID 是个好主意吗? 在编写下一个函数时,如何将activeDeposits.counter 连接到activeDeposits.depositor

【问题讨论】:

    标签: ethereum blockchain solidity smartcontracts


    【解决方案1】:
    uint public counter;
    
    mapping(uint = > Deposit) public ids; 
    
    function deposit() public payable {
    
        Deposit storage _deposit = ids[_counter]; 
    
        _deposit.depositAmount = msg.value; 
    
        _deposit.depositor = msg.sender;
        
        activeDeposits.push(_deposit);
    
        _counter++; 
    
        emit DepositMade(msg.sender, msg.value);
    }
    

    【讨论】:

    • 此处您同时使用了计数器和映射。你能只使用其中之一吗?
    • 另外,我用更新的代码创建了一个新线程:stackoverflow.com/questions/74730493/…
    • 在这种情况下,您需要同时使用计数器变量来实际计算存款并映射到存储每笔存款。
    【解决方案2】:

    您可以将 counter 移出结构:

    struct Deposit {
        uint256 depositAmount;
        address depositor;
    }
    

    您将计数器设置为顶级状态变量

    uint256 counter;
    

    你可以有一个将 counterId 映射到 Deposit 的映射

    mapping(uint156=>Deposti) public idToDeposit;
    

    然后通过id获取押金

    function getDepositByID(uint id)public view {
         idToDeposit[id]
    }
    

    你安装npm i @openzeppelin/contracts,导入``Counters

     import "../node_modules/@openzeppelin/contracts/utils/Counters.sol";
    

    在你的合同中:

    contract Test{
           // this means all Counters.Counter types in your contract loaded with the methods of Counters library
           using Counters for Counters.Counter;
           Counters.Counter private depositIds;
    }
    

    【讨论】:

    • 我看不出为基本的 uint256 ++counter 变量使用单独的库有什么意义。所以我从struct 中取出计数器,添加为状态变量,并添加了您建议的映射。通过输入 ID 查找特定存款的功能是什么?在哪里可以找到该 ID?
    • 我提到了图书馆,以防您看到它。它是省油的,但您在这里不需要。 particular deposit 是什么意思。您想寻找特定的存款,但您的搜索标准是什么。 by address 也许吧?
    • 通过特定存款,我的意思是如果一个人进行存款,我需要能够准确地查找该存款。一个地址可以充值多笔,地址查询无效。因此,每个存款都应该有一个唯一的 depositId。 function transfer (uint256 counter) public {activeDeposits[id].depositor.transfer(activeDeposits[id].depositAmount);} 所以基本上这个功能必须根据存款 ID 将存款金额转移给存款人。
    • 这就是映射发挥作用的原因。映射就像 python 中的字典或 javascript 中的对象。 idToDeposit[particularId] 会给你Deposit
    • 那么[particularId] = counter
    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    相关资源
    最近更新 更多