以太坊的参考资料

http://blog.youkuaiyun.com/fidelhl/article/details/50481859#comments以太坊的整体介绍以及写第一个智能合约

truffle开发环境官网简介http://truffle.readthedocs.io/en/latest/

今天一直在看serpent语言,看起来很简单,可是要自己写却不知道怎么下手,那个浏览器的IDE很好用但是应该不支持serpent吧,solidity会比较好



from serpent_setup import *
   
  def test_array_delete():
  code = '''\
  def delete(data:arr, index):
  mcopy(data+(items=index), data+(items=(index+1)), items=(len(data) - index - 1))
  shrink(data, len(data) - 1)
  return(data:arr)
  '''
  s = t.state() #t is in serpent_setup.py
  c = s.abi_contract(code)
  data = range(20)
  indeces = [0, 1, 14, 18, 19]
   
  PRINT('serpent code:')
  PRINT(code)
  PRINT()
  PRINT('lll:')
  PRINT(serpent.compile_to_lll(code))
   
  for index in indeces:
  PRINT('Test index %d' % index)
  PRINT('before delete:', data) #PRINT is defined in serpent_setup.py
  result = c.delete(data, index)
  PRINT('after delete: ', result)
  copy = data[:]
  copy.pop(index)
  PRINT('expected: ', copy)
  if copy == result:
  PRINT(PASSED) #PASSED and FAILED are defined in serpent_setup.py
  else:
  PRINT(FAILED)
   
  if __name__ == "__main__":
  test_array_delete()


my save_load.py


from serpent_setup import *
   
  code = '''\
  data junk[](length, data[])
 
  def saveData(key, data:arr):
  with location = ref(self.junk[key].data[0]):
  with end = len(data):
  with i = 0:
  while(i < end):
  sstore(location + i, data[i])
  i += 1
  self.junk[key].length = end
  return(key)
 
  def loadData(key):
  with location = ref(self.junk[key].data[0]):
  with count = self.junk[key].length:
  with result = array(count):
  with i = 0:
  while i < count:
  result[i] = sload(location + i)
  i += 1
  return(result:arr)
 
  def appendData(key, item):
  with temp = alloc(128):
  temp[0] = 0 #first data structure in the contract
  temp[1] = key
  temp[2] = 1 #second member of the structure
  temp[3] = 0
  with location = sha3(temp, items=4):
  temp[2] = 0 #first member of the structure
  with len = sha3(temp, items=3):
  with end = sload(len):
  sstore(location + end, item)
  sstore(len, end + 1)
 
  def doubleData(key):
  with location = ref(self.junk[key].data[0]):
  with end = self.junk[key].length:
  with i = 0:
  while i < end:
  sstore(location + i, sload(location + i) * 2)
  i += 1
  '''
   
  PRINT(serpent.compile_to_lll(code))
   
  s = t.state()
  c = s.abi_contract(code)
   
  data = range(10)
   
  try:
  PRINT(c.saveData(1, data, profiling=True))
  PRINT(c.loadData(1, profiling=True))
  PRINT(c.appendData(1, 10, profiling=True))
  PRINT(c.loadData(1, profiling=True))
  PRINT(c.doubleData(1, profiling=True))
  PRINT(c.loadData(1, profiling=True))
  except:
  PRINT(REDIRECT.getvalue())


save_load_tests.py


from serpent_setup import *
   
  code1 = '''\
  data junk[](length, data[])
 
  def saveData(key, data:arr):
  self.junk[key].length = len(data)
  with i = 0:
  while i < len(data):
  self.junk[key].data[i] = data[i]
  i += 1
 
  def loadData(key):
  with i = 0:
  with vals = array(self.junk[key].length):
  while i < len(vals):
  vals[i] = self.junk[key].data[i]
  i += 1
  return(vals:arr)
 
  def appendData(key, item):
  self.junk[key].data[self.junk[key].length] = item
  self.junk[key].length += 1
 
  def doubleData(key):
  with i = 0:
  while i < self.junk[key].length:
  self.junk[key].data[i] *= 2
  i += 1
  '''
   
  code2 = '''\
  data junk[](length, data[])
 
  def saveData(key, data:arr):
  with location = ref(self.junk[key].data[0]):
  with end = len(data):
  with i = 0:
  while(i < end):
  sstore(location + 1, data[i])
  i += 1
  self.junk[key].length = end
  return(key)
 
  def loadData(key):
  with location = ref(self.junk[key].data[0]):
  with count = self.junk[key].length:
  with result = array(count):
  with i = 0:
  while i < count:
  result[i] = sload(location + i)
  i += 1
  return(result:arr)
 
  def appendData(key, item):
  with location = ref(self.junk[key].data[0]):
  with end = self.junk[key].length:
  sstore(location + end, item)
  self.junk[key].length = end + 1
 
  def doubleData(key):
  with location = ref(self.junk[key].data[0]):
  with end = self.junk[key].length:
  with i = 0:
  while i < end:
  sstore(location + i, sload(location + i) * 2)
  i += 1
  '''
   
  code3 = '''\
  data junk[](length, data[])
 
  def saveData(key, data:arr):
  self.junk[key].length = len(data)
  save(self.junk[key].data[0], data, items=len(data))
 
  def loadData(key):
  return(load(self.junk[key].data[0], items=self.junk[key].length):arr)
 
  def appendData(key, item):
  with data = load(self.junk[key].data[0], items=self.junk[key].length):
  with new_data = array(len(data) + 1):
  mcopy(new_data, data, items=len(data))
  new_data[len(data)] = item
  save(self.junk[key].data[0], new_data, items=len(new_data))
  self.junk[key].length += 1
 
  def doubleData(key):
  with i = 0:
  with vals = load(self.junk[key].data[0], items=self.junk[key].length):
  while i < self.junk[key].length:
  vals[i] *= 2
  i += 1
  save(self.junk[key].data[0], vals, items=len(vals))
  '''
   
  def code_test(code, name):
  s = t.state()
  c = s.abi_contract(code)
  key = 0xCAFEBABE
   
  data = range(10)
  table = SimpleTable(name + ' - data: ' + str(data),
  ['', 'gas used', 'output', 'runtime'])
  r1 = c.saveData(key, data, profiling=True)
  table.add_row(['saveData', r1['gas'], r1['output'], r1['time']])
  r2 = c.loadData(key, profiling=True)
  table.add_row(['loadData', r2['gas'], r2['output'], r2['time']])
  r3 = c.appendData(key, 10, profiling=True)
  table.add_row(['appendData', r3['gas'], r3['output'], r3['time']])
  r4 = c.doubleData(key, profiling=True)
  table.add_row(['doubleData', r4['gas'], r4['output'], r4['time']])
  return table
   
  def test_save_load():
  s = t.state()
  for i, code in enumerate((code1, code2, code3)):
  name = 'code%d'%(i+1)
  table = code_test(code, name)
  table.print_table()
  PRINT()
   
  if __name__ == '__main__':
  test_save_load()


serpent_setup.py



A module for serpent tests without nonsense.
 
  Motivation:
  I write a lot of python scripts for testing serpent code,
  and I've noticed a few things which bug the heck out of me.
  One is that the pyethereum EVM prints out nonsense when it
  runs a contract. I'd have to delve into it's source to figure
  out how to disable this "feature" and I'm too lazy for that.
  Another thing that bugs me is that the serpent module prints
  out warning nonsense that doesn't seem to be disablable.
  Which leads me to my hacky solution...
 
  Method/Madness:
  The first part is to completely disable warning output. If
  something is going to break, I'd rather it just break and not
  complain about it so much and clutter my test output. So let's
  completely disable warnings! But that doesn't solve the whole
  problem, because some warnings are hard coded into the C++ code
  in the serpent module. The there is the EVM nonsense. To fix that
  I just redirect stdout to /dev/null, and define my own PRINT
  function that forces data to show in the terminal. And while I'm
  at it, I might as well throw the usual imports in since every
  test script I write will import this module. And maybe I should
  define some useful contants and functions...
  '''
   
  # disable warning crud about eggs and whatnot
  from warnings import simplefilter; simplefilter('ignore')
  # tester module!
  from ethereum import tester
  import serpent
  from cStringIO import StringIO
  import sys, os
   
   
  t = tester
  STDOUT = sys.stdout
  REDIRECT = StringIO()
  PASSED = 'TEST PASSED'
  FAILED = 'TEST FAILED'
  sys.stdout = REDIRECT #avoids nonsense when calling contract functions
  TAB = ' '*3
   
  #all caps cuz why not? :/
  def PRINT(*args, **kwds):
  '''Use this function to print, as stdout is redirected to devnull.
 
  All args have str called on them before they are "printed" to STDOUT.
  Keyword arguments:
  end -- A string to append to the end of the printed args.
  This defaults to os.linesep.
  seq -- A string to join the arguments by. Default is ' '.
  file -- A file-like object to use instead of STDOUT.
  Must have both write and flush methods.
  '''
  end = kwds.get('end', os.linesep)
  sep = kwds.get('sep', ' ')
  fileobj = kwds.get('file', STDOUT)
  outstr = sep.join(map(str, args))
  fileobj.write(outstr + end)
  fileobj.flush()
   
  def _to_str(item):
  if type(item) == float:
  return '%.6f'%item
  else:
  return str(item)
   
  class SimpleTable(object):
  '''A class for easily making tables and printing them.
 
  Tables have a title, column labels, and rows:
  +----------+----------+----------+
  | Table Test |
  +----------+----------+----------+
  +----------+----------+----------+
  | LabelA | LabelB | LabelC |
  +----------+----------+----------+
  |1371032652| 666555510|9814208081|
  +----------+----------+----------+
  |1191656453|7918551629|6032785125|
  +----------+----------+----------+
  |1952864215|6186265278|3779520336|
  +----------+----------+----------+
 
 
  The rows of a table can also be 'labeled', by having the
  first column label be the empty string, and each rows 'label'
  be the first element of the row:
  +----+----------+----------+----------+
  | Table Test 2 |
  +----+----------+----------+----------+
  +----+----------+----------+----------+
  | | LabelA | LabelB | LabelC |
  +----+----------+----------+----------+
  |row0|1371032652| 666555510|9814208081|
  +----+----------+----------+----------+
  |row1|1191656453|7918551629|6032785125|
  +----+----------+----------+----------+
  |row2|1952864215|6186265278|3779520336|
  +----+----------+----------+----------+
  '''
   
  def __init__(self, title, column_labels):
  self.title = title
  self.labels = map(str, column_labels)
  self.rows = []
  self.widths = map(len, self.labels)
  self.file = STDOUT
  self.final_message = None
   
  def add_row(self, row):
  '''Appends a row to the table.'''
  assert len(row) == len(self.labels), 'not enough columns in the row!'
  self.rows.append(map(_to_str, row))
  self.widths = map(max,
  zip(self.widths,
  map(len,
  self.rows[-1])))
   
  def set_file(self, fileobj):
  '''Sets the file object used for printing the table.'''
  self.file = fileobj
   
  def print_table(self):
  '''PRINTs table data prettily.'''
   
  def p(out):
  PRINT(out, file=self.file)
   
  bar, label_row = [''], ['']
  for width, label in zip(self.widths, self.labels):
  bar.append('-' * (width))
  label_row.append(str(label).center(width))
  bar.append(''); bar = '+'.join(bar)
  label_row.append(''); label_row = '|'.join(label_row)
   
  p('+' + '-'*(len(bar) - 2) + '+')
  p('|' + self.title.center(len(bar) - 2) + '|')
  p('+' + '-'*(len(bar) - 2) + '+')
   
  p(bar)
  p(label_row)
  p(bar)
   
  for row in self.rows:
  adjusted_row = ['']
  for width, item in zip(self.widths, row):
  adjusted_row.append(str(item).rjust(width))
  adjusted_row.append('')
  p('|'.join(adjusted_row))
  p(bar)
   
  if self.final_message:
  p(bar)
  p('+' + self.final_message.center(len(bar) - 2) + '+')
  p(bar)
   
  def main():
  import random
  table = SimpleTable('Table Test',
  ['LabelA', 'LabelB', 'LabelC'])
   
  for i in range(3):
  row = []
  for j in range(3):
  row.append(random.randrange(10**10))
  table.add_row(row)
   
  table.print_table()
   
  PRINT()
   
  named_rows = SimpleTable(table.title + ' 2',
  [''] + table.labels)
   
  for i, row in enumerate(table.rows):
  named_rows.add_row(['row%d'%i] + row)
   
  named_rows.print_table()
   
  if __name__ == '__main__':
  main()


参考https://github.com/AugurProject/augur-core/tree/master/tests/serpent_tests

【技术背景】区块链,是一个分布式的共享账本和数据库,具有去中心化、不可篡改、可追溯、公开透明等特点。区块链技术作为科技创新的代表和未来技术的发展方向,已经上升至国家战略高度。它将为解决信息不对称问题、创造信任与合作机制等提供丰富的应用空间,也会是未来我们技术自主创新、引领产业变革的重要突破口。比特币被认为是区块链技术1.0版的应用,主要实现的是电子现金的分布式记账转账功能。而随着技术的不断发展更新,越来越多的人希望突破“账本”的限制,从而可以把这项未来技术应用在更广阔的领域。以太坊(Ethereum)为代表的第二代区块链公链项目,就是其中的佼佼者。与比特币不同,以太坊的定位是一个“世界计算机”。以区块链作为底层存储技术,我们不仅可以记账转账,而且可以构建“智能合约”(smart contract)定义程序化的处理流程,进而实现区块链上运行的“去中心化应用”(DApp)。以太坊项目自提出后就受到了广泛关注,快速的发展和壮大,而且由于其“分布式应用平台”而非“分布式账本”的定位,越来越多的开发人员开始以以太坊为基础设施,在上面开发DApp。随着更多开发人员的参与,和项目的逐步落地,以太坊已成为从事区块链学习和开发不可或缺的一个环节;既了解区块链底层原理、又熟悉以太坊架构、还能基于以太坊开发DApp的专业人才,也成为了各大公司发力区块链技术储备的重点对象。【课程简介】本套以太坊课程,对以太坊基础理论知识和架构做了系统的梳理和深入的阐述,并对solidity和DApp的开发做了系统讲解,另外还对以太坊白皮书、黄皮书做了介绍;为有志于学习区块链技术、了解以太坊底层架构和DApp开发原理的工程师提供学习平台和帮助。本教程内容主要分为五大部分:以太坊基础、以太坊原理和架构、以太坊编程及应用、合约工作流以及原理深入分析。通过学习本套课程,可以使学习者对以太坊有充分的认识,对整个区块链技术有更深刻的理解,对区块链应用开发有更加整体的领悟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值