types.gno
2.72 Kb ยท 151 lines
1// TODO: this is an example, and needs to be fixed up and tested.
2
3package bank
4
5// NOTE: unexposed struct for security.
6type order struct {
7 from Address
8 to Address
9 amount Coins
10 processed bool
11}
12
13// NOTE: unexposed methods for security.
14func (ch *order) string() string {
15 return "TODO"
16}
17
18// Wraps the internal *order for external use.
19type Order struct {
20 *order
21}
22
23// XXX only exposed for demonstration. TODO unexpose, make full demo.
24func NewOrder(from Address, to Address, amount Coins) Order {
25 return Order{
26 order: &order{
27 from: from,
28 to: to,
29 amount: amount,
30 },
31 }
32}
33
34// Panics if error, or already processed.
35func (o Order) Execute() {
36 if o.order.processed {
37 panic("order already processed")
38 }
39 o.order.processed = true
40 // TODO implemement.
41}
42
43func (o Order) IsZero() bool {
44 return o.order == nil
45}
46
47func (o Order) From() Address {
48 return o.order.from
49}
50
51func (o Order) To() Address {
52 return o.order.to
53}
54
55func (o Order) Amount() Coins {
56 return o.order.amount
57}
58
59func (o Order) Processed() bool {
60 return o.order.processed
61}
62
63//----------------------------------------
64// Escrow
65
66type EscrowTerms struct {
67 PartyA Address
68 PartyB Address
69 AmountA Coins
70 AmountB Coins
71}
72
73type EscrowContract struct {
74 EscrowTerms
75 OrderA Order
76 OrderB Order
77}
78
79func CreateEscrow(terms EscrowTerms) *EscrowContract {
80 return &EscrowContract{
81 EscrowTerms: terms,
82 }
83}
84
85func (esc *EscrowContract) SetOrderA(order Order) {
86 if !esc.OrderA.IsZero() {
87 panic("order-a already set")
88 }
89 if esc.EscrowTerms.PartyA != order.From() {
90 panic("invalid order-a:from mismatch")
91 }
92 if esc.EscrowTerms.PartyB != order.To() {
93 panic("invalid order-a:to mismatch")
94 }
95 if !esc.EscrowTerms.AmountA.Equal(order.Amount()) {
96 panic("invalid order-a amount")
97 }
98 esc.OrderA = order
99}
100
101func (esc *EscrowContract) SetOrderB(order Order) {
102 if !esc.OrderB.IsZero() {
103 panic("order-b already set")
104 }
105 if esc.EscrowTerms.PartyB != order.From() {
106 panic("invalid order-b:from mismatch")
107 }
108 if esc.EscrowTerms.PartyA != order.To() {
109 panic("invalid order-b:to mismatch")
110 }
111 if !esc.EscrowTerms.AmountB.Equal(order.Amount()) {
112 panic("invalid order-b amount")
113 }
114 esc.OrderA = order
115}
116
117func (esc *EscrowContract) Execute() {
118 if esc.OrderA.IsZero() {
119 panic("order-a not yet set")
120 }
121 if esc.OrderB.IsZero() {
122 panic("order-b not yet set")
123 }
124 // NOTE: succeeds atomically.
125 esc.OrderA.Execute()
126 esc.OrderB.Execute()
127}
128
129//----------------------------------------
130// TODO: actually implement these in std package.
131
132type (
133 Address string
134 Coins []Coin
135 Coin struct {
136 Denom bool
137 Amount int64
138 }
139)
140
141func (a Coins) Equal(b Coins) bool {
142 if len(a) != len(b) {
143 return false
144 }
145 for i, v := range a {
146 if v != b[i] {
147 return false
148 }
149 }
150 return true
151}