Class: Contract

Inherits:
Object
  • Object
show all
Includes:
Safe
Defined in:
lib/universum/contract.rb

Constant Summary collapse

@@directory =
{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(address = nil, *args) ⇒ Contract

Returns a new instance of Contract.



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/universum/contract.rb', line 68

def initialize( address=nil, *args )
  ##  fix/todo:  use/lookup proper addr from contract
  ## construct address for now from object_id
  address = "0x#{(object_id << 1).to_s(16)}"  if address.nil?
  @address = Address.new( address )
  @storage = Storage.new

  ###########
  # note: does NOT auto-call setup - why? why not?
  #   use create !!!!!!

  ## todo: make initialize private - why? why not?
end

Class Method Details

.[](key) ⇒ Object



53
# File 'lib/universum/contract.rb', line 53

def self.[]( key ) find_by_address( key ); end

.allObject



56
# File 'lib/universum/contract.rb', line 56

def self.all() @@directory.values; end

.at(key) ⇒ Object

another “classic” alias for find_by_address



52
# File 'lib/universum/contract.rb', line 52

def self.at( key) find_by_address( key ); end

.create(*args) ⇒ Object

account (builtin) services / transaction methods



62
63
64
65
66
# File 'lib/universum/contract.rb', line 62

def self.create( *args )
  klass = new( nil, *args )
  klass.setup( *args )
  klass
end

.find(key) ⇒ Object

make find_by_address the default finder



51
# File 'lib/universum/contract.rb', line 51

def self.find( key ) find_by_address( key ); end

.find_by_address(key) ⇒ Object



46
47
48
49
50
# File 'lib/universum/contract.rb', line 46

def self.find_by_address( key )
   ## clean key (allow "embedded" class name e.g 0x4de2ee8 (SatoshiDice))
   key = key.gsub(/\(.+\)/, '' ).strip
   @@directory[ key ];
end

.load(path) ⇒ Object

load “class-less” contract

e.g.   SathoshiDice = Contract.load( './sathoshi_dice' )


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/universum/contract.rb', line 10

def self.load( path )
  extname = File.extname( path )   #=> ".rb"
  if extname == '.rb'
    ## do nothing
  else
    ## "convenience" helper - (auto-)add .rb extension
    path = "#{path}.rb"
  end

  code = File.open( path, 'r:bom|utf-8' ) { |f| f.read }

  ## auto-patch!!!!
  ##   change all ivars to use storage
  ##   e.g.  @greeting                  => storage.greeting
  ##         @balance_of[ msg.sender ]  => storage.balance_of[ msg.sender ]
  ##         ...
  ##
  ##  todo/fix: check for possible class variables!! (e.g. @@logger or something)
  ##               make regex "smarter"
  code = code.gsub( /(@{1,})([a-z][a-zA-Z0-9_]*)/ ) do |_|
    if $1.size == 1
       puts "auto-patching contract code >#{$1}#{$2}< to >storage[ :#{$2} ]<"
       "storage[ :#{$2} ]"
    else
       ## assume class variable - skip - keep as is
       "#{$1}#{$2}"
    end
  end

  klass = Class.new( Contract )
  klass.class_eval( code )   ## note: use class_eval (NOT instance_eval)
  klass
end

.payable(*args) ⇒ Object

function sig(nature) macro for types (dummy for now) e.g. use like

payable :process
payable :initialize
payable :bet, Integer
payable :lend_money, Address => Bool   ## returns Bool


98
# File 'lib/universum/contract.rb', line 98

def self.payable( *args ); end

.store(key, o) ⇒ Object

store (add) new contract object (o) to hash / directory



55
# File 'lib/universum/contract.rb', line 55

def self.store( key, o ) @@directory.store( key, o ); end

Instance Method Details

#addressObject



87
# File 'lib/universum/contract.rb', line 87

def address() @address; end

#assert(condition, message = nil) ⇒ Object

todo/fix: use module Assertions and include in contract class



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/universum/contract.rb', line 111

def assert( condition, message=nil )
  ## note: use message to avoid conflict with msg helper/builtin in contract!!!
  if condition == true
    ## do nothing
  else
    if message
      raise "Contract Assertion Failed; Contract Halted (Stopped): #{message}"
    else
      raise 'Contract Assertion Failed; Contract Halted (Stopped)'
    end
  end
end

#blockObject



128
# File 'lib/universum/contract.rb', line 128

def block()      Universum.block;        end

#blockhash(number) ⇒ Object



129
130
131
132
# File 'lib/universum/contract.rb', line 129

def blockhash( number )
  ## todo/fix: only allow going back 255 blocks; check if number is in range!!!
  Universum.blockhash( number )
end

#log(event) ⇒ Object



126
# File 'lib/universum/contract.rb', line 126

def log( event ) Universum.log( event ); end

#msgObject



127
# File 'lib/universum/contract.rb', line 127

def msg()        Universum.msg;          end

#setupObject



83
84
85
# File 'lib/universum/contract.rb', line 83

def setup
  # default (built-in) setup; do nothing
end

#storageObject



90
# File 'lib/universum/contract.rb', line 90

def storage() @storage; end

#thisObject

returns “embedded” address of current contract (that is, us!)



88
# File 'lib/universum/contract.rb', line 88

def this()    @address; end