如何改善智能联系人设计以区分同一域对象的数据及其操作功能? [英] How to improve smart contact design in order to distinguish data and their manipulation functions for the same domain object?

查看:59
本文介绍了如何改善智能联系人设计以区分同一域对象的数据及其操作功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在重新部署合同方面遇到问题.每次在新合同版本部署期间更改某些逻辑时,我们都会丢失所有与合同相关的数据(存储在数组,映射中).然后,我们需要执行数据加载过程,以将环境还原到所需状态,这是耗时的操作.我试图将合同拆分为两个合同(AbcDataContract,AbcActionsContract),但是遇到访问映射的问题:错误:索引表达式必须是类型,映射或数组(是函数(bytes32)),它查看外部返回值(uint256) )) 初始合同:

We have a problem with contract redeploying. Each time when some logic is changed during new contract version deployment we are loosing all contract related data (which are stored in arrays, mappings). Then we need to execute data load procedures in order to restore environment to desired state which is time consuming action. I tried to split contract to tow ones (AbcDataContract, AbcActionsContract) but faced with problem of accessing to the mappings : Error: Indexed expression has to be a type, mapping or array (is function (bytes32) view external returns (uint256)) Initial contract :

contract AbcContract {

EntityA[] public entities;
mapping (bytes32 => uint) public mapping1;
mapping (bytes32 => uint[]) public mapping2;
mapping (bytes32 => uint[]) public mapping3;

/* Events */
event Event1(uint id);
event Event2(uint id);

/* Structures */
struct EntityA {
    string field1;
    string field2;
    bool field3;
    uint field4;
    Status field5;
}

enum Status {PROPOSED, VOTED, CONFIRMED}

function function1(...) returns (...)
function function2(...) returns (...)
function function3(...) returns (...)
function function4(...) returns (...)
function function5(...) returns (...)

}

重构合同:

contract AbcDataContract {

EntityA[] public items;
mapping (bytes32 => uint) public mapping1;
mapping (bytes32 => uint[]) public mapping2;
mapping (bytes32 => uint[]) public mapping3;

/* Events */
event Event1(uint id);
event Event2(uint id);

/* Structures */
struct EntityA {
    string field1;
    string field2;
    bool field3;
    uint field4;
    Status proposalStatus;
}

enum Status {PROPOSED, VOTED, CONFIRMED}

}

contract AbcActionsContract {

AbcDataContract abcDataContract;

/* constructor */
function AbcActionsContract(address _AbcDataContract) {
    abcDataContract = AbcDataContract(_AbcDataContract);
}

/* accessing to the mapping like abcDataContract.mapping1[someId] will raise Solidity compile error  */
function function1(...) returns (...)
/* accessing to the mapping like abcDataContract.mapping2[someId] will raise Solidity compile error  */
function function2(...) returns (...)
/* accessing to the mapping like abcDataContract.mapping3[someId] will raise Solidity compile error  */
function function3(...) returns (...)
function function4(...) returns (...)
function function5(...) returns (...)

}

当存储过程/视图/其他逻辑(而非数据对象)中的逻辑更改通常不影响数据本身时,我们希望实现与数据库开发中相同的方法.解决此问题的最佳设计解决方案是什么?

We would like to implement approach like we have in DB development when logic changes in stored procedures/views/other not data objects usually does not affect data itself. What is the best design solution for this problem ?

推荐答案

问题的第一部分非常简单.要访问其他合同中的公共映射,只需使用():

The first part of your question is fairly easy. To access a public mapping in another contract, simply use ():

abcDataContract.mapping1(someId)

当然,您也可以提供自己的对AbcDataContract的访问方法,而不是也使用公共映射.如果您走这条路,我建议您通过一个界面来访问您的数据合同

Of course, you can also provide your own access methods to AbcDataContract instead of using the public mapping as well. If you go down this path, I'd recommend going through an interface to access your data contract

对于问题的设计部分,看来您走在正确的道路上.将您的数据存储分成自己的合同具有巨大的好处.由于您不必担心数据迁移的问题,因此不仅易于部署,而且部署新合同的成本也低得多.

As for the design part of your question, it looks like you're on the right track. Separating your data store into its own contract has huge benefits. Not only is it much easier to deploy since you don't have to worry about migrating your data, but it's also much cheaper to deploy the new contract.

话虽这么说,但我想指出一些与您发布的重构版本有关的事情.

That being said, there's a couple things I want to point out with the refactored version you posted.

  1. 很难说出您打算使用Struct1做些什么.在您的伪代码中没有对它的引用.除非它们是internal调用(或者您明确分解了该结构),否则您无法从Solidity中的函数返回结构.
  2. 类似地,您不能在合同之间返回字符串.如果计划在AbcActionsContract中使用Struct1.field1/2,则需要将它们转换为bytes32.
  3. 您可能想要将事件定义移至业务逻辑合同中.
  1. It's hard to tell what you're planning on doing with Struct1. There's no reference to it in your pseudocode. You can't return structs from functions in Solidity unless they are internal calls (or you explicitly decompose the struct).
  2. Similarly, you can't return strings between contracts. If you plan on using Struct1.field1/2 in AbcActionsContract, you'll need to convert them to bytes32.
  3. You'll probably want to move your event definitions into your business logic contract.

将数据存储与业务逻辑分开是升级合同的关键组成部分.使用接口和库可以帮助您.有几篇博客文章解决了这个问题.我个人建议从此,并进行后续操作此处.

Separating your data store from your business logic is a key component to upgrading contracts. Using interfaces and libraries help with this. There are several blog posts out there addressing this issue. I personally recommend starting with this one along with a follow up here.

这篇关于如何改善智能联系人设计以区分同一域对象的数据及其操作功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆