首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Struct数组作为参数的智能合同工厂

使用Struct数组作为参数的智能合同工厂
EN

Stack Overflow用户
提问于 2022-12-04 18:36:20
回答 1查看 17关注 0票数 0

我正在使用一个CampaignFactory合同来创建多个活动合同实例,并跟踪它们。每一个战役都是由一个叫做奖励的结构来初始化的。当我尝试在混合中使用createCampaign创建一个新的活动时,我有以下错误:

代码语言:javascript
复制
[vm]from: 0x5B3...eddC4to: CampaignFactory.createCampaign((uint256,uint256,string)[]) 0xd91...39138value: 0 weidata: 0x6d9...00000logs: 0hash: 0xa4d...ad5fd
transact to CampaignFactory.createCampaign errored: VM error: revert.

这是我的代码:

代码语言:javascript
复制
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;

struct Reward {
    uint256 contribution;
    uint256 maxNumber;
    string ImageLink;
}

contract CampaignFactory {

    Campaign[] public deployedCampaigns;

    function createCampaign(Reward[] memory _rewards)
        public
    {
        Campaign newCampaign = new Campaign(msg.sender);

        for (uint256 i = 0; i < _rewards.length; i++) {
            newCampaign.createReward(
                _rewards[i].contribution,
                _rewards[i].maxNumber,
                _rewards[i].ImageLink
            );
        }
        deployedCampaigns.push(newCampaign);
    }

    function getDeployedCampaigns()
        public
        view
        returns (Campaign[] memory)
    {
        return deployedCampaigns;
    }
}

contract Campaign {
    Reward[] public rewards;
    address public manager;

    modifier restricted() {
        require(msg.sender == manager);
        _;
    }
    constructor(address creator) {
        manager = creator;
    }

    function createReward(
        uint256 _contribution,
        uint256 _maxNumber,
        string memory _imageLink
    ) public restricted {
        Reward memory newReward = Reward({
            contribution: _contribution,
            maxNumber: _maxNumber,
            ImageLink: _imageLink
        });

        rewards.push(newReward);
    }
}
EN

回答 1

Stack Overflow用户

发布于 2022-12-04 19:53:51

当您部署Campaign契约时,用户的地址被分配给manager

然后调用createReward()函数。它的restricted修饰符只允许manager调用函数。但是该函数是由您的契约调用的,而不是由用户直接调用的。它会失败验证并恢复事务。

您可以在tx.origin中获取原始事务发件人的地址,但使用它进行授权是一种安全风险-- https://swcregistry.io/docs/SWC-115

因此,您可以在函数参数中传递用户地址,并在那里验证它。

代码语言:javascript
复制
function createCampaign(Reward[] memory _rewards)
    public
{
    // pass the factory address to later validate `msg.sender`
    Campaign newCampaign = new Campaign(address(this), msg.sender);

    for (uint256 i = 0; i < _rewards.length; i++) {
        // pass the user address to validate if they're the `manager`
        newCampaign.createReward(
            _rewards[i].contribution,
            _rewards[i].maxNumber,
            _rewards[i].ImageLink,
            msg.sender
        );
    }
    deployedCampaigns.push(newCampaign);
}
代码语言:javascript
复制
address factory;
address public manager;

modifier restrictedThroughFactory(address user) {
    require(msg.sender == factory && user == manager);
    _;
}

modifier restricted() {
    require(msg.sender == manager);
    _;
}

constructor(address _factory, address creator) {
    factory = _factory;
    manager = creator;
}

// original function that can be still executed directly by the user
function createReward(
    uint256 _contribution,
    uint256 _maxNumber,
    string memory _imageLink
) public restricted {
    _createReward(_contribution, _maxNumber, _imageLink);
}

// overloaded function that can be only executed by the Factory contract
// reverts if the `user` (can be passed only by the Factory contract) is not the `manager`
function createReward(
    uint256 _contribution,
    uint256 _maxNumber,
    string memory _imageLink,
    address user
) public restrictedThroughFactory(user) {
    _createReward(_contribution, _maxNumber, _imageLink);
}

function _createReward(
    uint256 _contribution,
    uint256 _maxNumber,
    string memory _imageLink
) internal {
    Reward memory newReward = Reward({
        contribution: _contribution,
        maxNumber: _maxNumber,
        ImageLink: _imageLink
    });

    rewards.push(newReward);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74679754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档