首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >后端坚固

后端坚固
EN

Ethereum用户
提问于 2023-03-30 04:04:13
回答 2查看 49关注 0票数 1

我正在研究稳健作为后端,我创造了这个聪明的合同。我想使用它来进行用户身份验证,并将他们的数据存储在智能契约中。我希望用户在通过Metamask注册时自动被添加到授权用户列表中,如果他们有带有地址X的特殊令牌,他们应该能够将数据存储为一个字符串。数据应按类型排序,检索数据应根据授权用户的地址和需要检索的数据类型进行。在我完全搞不懂之前,请帮助我理解这个任务。

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

// Contract Definition
contract GyberStorage{

// Owner address
    address private owner;

    // Addresses that can call contract functions

    address[] private authorizedAddresses;

    // Data structure

    struct Data{
        uint256 id;
        string dataType;
        address userAddress;
        string link;
    }

    // Data storage
    mapping(uint256 => Data) private data;

    // Contract constructor
    constructor(){
        owner = msg.sender;
    }

    // Modifier to check that the function is called only by the contract owner
    modifier onlyOwner(){
        require(msg.sender == owner,'Only owner can call this function');
        _;
    }

    // Modifier to check that the function is called only by an authorized address
    modifier onlyAuthorized(){
        // Initializing a flag variable
    bool isAuthorized = false;

        // Checking if the calling address is authorized
    for (uint i = 0;i < authorizedAddresses.length;i++){
        if (authorizedAddresses[i] == msg.sender){
            isAuthorized = true;
            break;
        }
    }
    
       // If the address is not authorized, an exception is generated
    require(isAuthorized,"Not authorized");
    _;

    }

    // Function to add an authorized address
    function addAuthorizedAddress(address _address) public onlyOwner {
        authorizedAddresses.push(_address);
    }

    // Function to remove an authorized address
    function removeAuthorizedAddress(address _address) public onlyOwner {
        for (uint i = 0; i < authorizedAddresses.length; i++){
            if (authorizedAddresses[i] == _address){
                delete authorizedAddresses[i];
            }
        }
    }

    // Function to add data to the storage
    function addData(uint256 id, string memory dataType, address userAddress, string memory link) public onlyAuthorized {

        // Checking that the data with the given ID has not been added yet
    require(data[id].id == 0);

        // Adding data to the storage
    data[id] = Data(id, dataType, userAddress, link);

    }

    // Function to retrieve data from the storage
    function getData(uint256 id,address userAddress,string memory dataType ) public view returns (uint256, string memory, address , string memory){
        // Checking that the data with the given ID is in the storage
    require(data[id].id != 0,"Data with this ID does not exist");

        // Returning the data
    return (data[id].id, data[id].dataType, data[id].userAddress, data[id].link);
    }

    // Function to update data in the storage
    function updateData(uint256 id, string memory dataType, address userAddress, string memory linkIpfs) public onlyAuthorized{

        // Checking that the data with the given ID is in the storage
    require(data[id].id != 0,"Data with this ID does not exist");
    // Removing data from the storage
    delete data[id];
    }

}

我感兴趣的是如何修改代码,使其与我描述的功能相匹配,并希望对智能协议的任何一般安全性和性能建议表示感谢。

EN

回答 2

Ethereum用户

回答已采纳

发布于 2023-03-30 04:35:23

我可以为您提供的一个快速提示是,为authorizedAddresses使用映射而不是数组,以增强代码的安全性和性能。

  • 原因是,如果authorizedAddresses列表大量增长,则可能导致事务在遍历数组时耗尽气体,您的事务将始终恢复,从而导致合同中的拒绝服务。
  • 如果您想要完成的是验证某个地址/调用者是否被授权做某事,您可以使用映射(address=>bool)并将所有这些授权地址设置为true。

发自:

代码语言:javascript
复制
// Addresses that can call contract functions
address[] private authorizedAddresses;

代码语言:javascript
复制
// Addresses that can call contract functions
mapping(address => bool) private authorizedAddresses;

您可以创建一个单独的函数,您需要调用这个函数才能设置为true -- authorizedAddresses,您可以在这个函数上具有创造性,可以一次设置为true一个地址,接收一个地址数组,并在同一个调用中将它们设置为true (单独)

.

希望这对你有所帮助,并给你一些关于良好实践的看法。

关于您希望在合同中实现的其他方面,请注意,函数可以处理的计算能力受到气体的限制,事务消耗的资源越多,处理它们的实际花费就越多。

票数 0
EN

Ethereum用户

发布于 2023-03-30 07:52:24

不要把稳固作为后盾!原因如下:

  1. 这要花很多钱!远远超过支付服务器成本或使用免费的auth提供者。
  2. 每一次交互都必须由您的dapp用户签名和付费(想象一下每次您从白色模式切换到黑暗模式时都要登录)。
  3. 它是不容易可更新/可扩展的。因为Smart是不可变的,在部署后永远不能更改。例如,部署后不能扩展Data结构或修复安全漏洞。
  4. 排序是不可行的,因为你有少量的执行时间。无论是在添加/删除/修改链上数据时,都有大量的开销。在这种方法中,用户通过使用合同的总用户数量来进行这些事务的开销是不公平的。或者,您需要运行一个节点来查询所有数据,并在排序服务器端执行排序(这将违背将solidity用作后端的目的)。

我希望用户在通过Metamask注册时,自动添加到授权用户列表中。

这是不可能的,因为煤气费用通常由与合同交互的用户支付,您不能自动地做任何事情。有一种用加油站网络为用户付费的方法,但这是相当复杂的,而且我不认为您真的想为用户付费,因为再次与区块链交互比使用集中的第三方auth提供商要昂贵得多。您可能想要的是类似于免费的火源8月。然后,将用户的地址与帐户一起存储。

票数 2
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/148227

复制
相关文章

相似问题

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