我的工作是关于Smart合同开发的。使用(py)ethereum和蛇,
在阅读"“以太与蛇的程序员指南”“时,我在5.9点上看到:
..。可以使用数据声明声明持久数据结构。这允许对数组和元组进行声明。..。
以及:
..。对于简单的存储,self.storage[]是有用的,但是对于较大的契约,我们建议使用数据(当然,除非您需要键值存储).
代码示例:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import serpent
from ethereum import tester, utils, abi
serpent_code = '''
data mystorage[]
def test_data_storage(key,value):
if not self.mystorage[key]:
self.mystorage[key]=value
return(1)
else:
return(0)
def get_value_mystorage(key):
if not self.mystorage[key]:
return(0)
else:
return(self.mystorage[key])
def test_self_storage(key,value):
if not self.storage[key]:
self.storage[key]=value
return(1)
else:
return(0)
def get_value_self_storage(key):
if not self.storage[key]:
return(0)
else:
return(self.storage[key])
'''
s = tester.state()
c = s.abi_contract(serpent_code)
#example with self storage
c.test_self_storage("keyA",1)
print c.get_value_self_storage("keyA") #store and access data works in self.storage!
#example with mystorage
c.test_data_storage("keyB",2)
print c.get_value_mystorage("keyB") #store and access data works in data as persistant data storage!
#fail example with complex data
my_complex_data={"keyA":1,"keyB":2, "keyC":[1,2,3], "keyD":{"a":1,"b":2}}
c.test_data_storage("keyComplex",my_complex_data)
#don't store anything because error:
# ethereum.abi.ValueOutOfBounds: {'keyC': [1, 2, 3], 'keyB': 2, 'keyA': 1, 'keyD': {'a': 1, 'b': 2}}我的问题是:什么是最好的方法,以及如何存储复杂的数据(请参阅代码中的my_complex_data变量),就像字典中包含其他数据一样。(或者数组作为键值)作为持久的数据结构?
是否有人知道这是否可能,以及如何将任何类结构存储为持久的数据结构?
发布于 2018-05-20 06:12:01
:请注意,根据这个Vitalik Tweet的说法,蛇现在是一种“过时的技术”。
毒蛇README已被更新为:
作为一种低级语言,除非你真的知道自己在做什么,否则不建议使用蛇来构建应用程序。创建者建议将稳健性作为一种默认的选择,如果您想要接近金属的优化,可以选择LLL,如果您喜欢Vyper的功能,尽管它仍然是实验性的。
如果您想从Python中编写Ethereum合同以发布生产产品,那么开始考虑迁移到坚固性或维珀 (这仍然是一种“新的实验性编程语言”)。
关于我的问题,我最终找到了一个(棘手/肮脏)的解决方案,即在将复杂数据压缩到持久数据存储之前对其进行编码,然后在从存储中检索数据后进行解码。
请参阅下面更新的代码:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import serpent
import json,math
from ethereum import tester, utils, abi
serpent_code = '''
data mystorage[]
def test_data_storage(key,value):
if not self.mystorage[key]:
self.mystorage[key]=value
return(1)
else:
return(0)
def get_value_mystorage(key):
if not self.mystorage[key]:
return(0)
else:
return(self.mystorage[key])
def test_self_storage(key,value):
if not self.storage[key]:
self.storage[key]=value
return(1)
else:
return(0)
def rebuild_complex_data_storage(key):
if not self.storage[key]:
return(0)
def get_value_self_storage(key):
if not self.storage[key]:
return(0)
else:
return(self.storage[key])
def put_complex_data_storage(key,value=""):
self.storage[key]=value
def get_complex_data_storage(key):
return(self.storage[key])
'''
s = tester.state()
c = s.abi_contract(serpent_code)
#example with self storage
c.test_self_storage("keyA",1)
print c.get_value_self_storage("keyA") #store and access data works in self.storage!
#example with mystorage
c.test_data_storage("keyB",2)
print c.get_value_mystorage("keyB") #store and access data works in data as persistant data storage!
start_block="99699"
def block_chain_encode(c,key,my_complex_data):
#ENCODE PART
global start_block
print "\n","*","ENCODE","*"
#fail example with complex data
my_complex_data_json_format=unicode(json.dumps(my_complex_data))
int_str=start_block
for each in my_complex_data_json_format:
int_str=int_str+ str(ord(each)).zfill(4)
int_str=int_str+start_block
print int_str
#toHex = lambda x:"".join([hex(ord(c))[2:].zfill(2) for c in x])
print "need to declare 32 bit words", math.ceil(len(int_str)/32.),"times"
#max 32 char for each key
max_size=int(math.ceil(len(int_str)/32.))
for i in range(0,max_size):
block_content=int_str[i*32:(i+1)*32]
print "block",i," content",block_content
if i==0:
c.test_data_storage("keyComplex_len",max_size)
key="keyComplex_"+str(i).zfill(3)
res=c.test_data_storage(key,int(block_content)) #store block part in block chain
print " - substorage",key,"",
#print "data storage part is done !"
return 1
def block_chain_decode(c,key):
#DECODE PART
global start_block
print "\n","*","DECODE","*"
int_str=""
lenght= c.get_value_mystorage("keyComplex_len") #get lenght to know how many block we need to get for all data from block chain
for i in range(0,lenght):
key="keyComplex_"+str(i).zfill(3)
print key,c.get_value_mystorage(key)
int_str=int_str+str(c.get_value_mystorage(key))
content_=""
sp_int_str= int_str.split(start_block)
if len(sp_int_str)==3:
if sp_int_str[-1]==sp_int_str[0] and sp_int_str[0]=="":
print "ok"
content_=sp_int_str[1]
js_str=""
if content_!="":
for i in range(0,int(len(content_)/4.)):
js_str+=chr(int(content_[i*4:(i+1)*4])) #recover char from asci code
my_complex_data=json.loads(js_str)
return my_complex_data
#define complex data
my_complex_data={"keyA":1,"keyB":2, "keyC":[1,2,3], "keyD":{"a":1,"b":2}}
print "Initial complex data",my_complex_data
#encode and push to block chain
block_chain_encode(c,"keyComplex",my_complex_data)
#get complex variable from block chain
my_complex_data_back = block_chain_decode(c,"keyComplex")
#acces data
print my_complex_data_back["keyD"]["a"]+my_complex_data_back["keyD"]["b"]
print "Extracted complex data from blockchain",my_complex_data
print "Integrity test pass:",my_complex_data_back==my_complex_data返回:
1
2
Initial complex data {'keyC': [1, 2, 3], 'keyB': 2, 'keyA': 1, 'keyD': {'a': 1, 'b': 2}}
* ENCODE *
99699012300340107010101210067003400580032009100490044003200500044003200510093004400320034010701010121006600340058003200500044003200340107010101210065003400580032004900440032003401070101012100680034005800320123003400970034005800320049004400320034009800340058003200500125012599699
need to declare 32 bit words 9.0 times
block 0 content 99699012300340107010101210067003
- substorage keyComplex_000 block 1 content 40058003200910049004400320050004
- substorage keyComplex_001 block 2 content 40032005100930044003200340107010
- substorage keyComplex_002 block 3 content 10121006600340058003200500044003
- substorage keyComplex_003 block 4 content 20034010701010121006500340058003
- substorage keyComplex_004 block 5 content 20049004400320034010701010121006
- substorage keyComplex_005 block 6 content 80034005800320123003400970034005
- substorage keyComplex_006 block 7 content 80032004900440032003400980034005
- substorage keyComplex_007 block 8 content 8003200500125012599699
- substorage keyComplex_008
* DECODE *
keyComplex_000 99699012300340107010101210067003
keyComplex_001 40058003200910049004400320050004
keyComplex_002 40032005100930044003200340107010
keyComplex_003 10121006600340058003200500044003
keyComplex_004 20034010701010121006500340058003
keyComplex_005 20049004400320034010701010121006
keyComplex_006 80034005800320123003400970034005
keyComplex_007 80032004900440032003400980034005
keyComplex_008 8003200500125012599699
ok
3
Extracted complex data from blockchain {'keyC': [1, 2, 3], 'keyB': 2, 'keyA': 1, 'keyD': {'a': 1, 'b': 2}}
Integrity test pass: Truehttps://stackoverflow.com/questions/43281811
复制相似问题