1This is a simple test realm contract that demonstrates how to use the banker.
2
3See [gno.land/r/demo/banktest/banktest.go](/r/demo/banktest/banktest.go) to see the original contract code.
4
5This article will go through each line to explain how it works.
6
7```go
8package banktest
9```
10
11This package is locally named "banktest" (could be anything).
12
13```go
14import (
15 "std"
16)
17```
18
19The "std" package is defined by the gno code in stdlibs/std/. </br> Self explanatory; and you'll see more usage from std later.
20
21```go
22type activity struct {
23 caller std.Address
24 sent std.Coins
25 returned std.Coins
26 time time.Time
27}
28
29func (act *activity) String() string {
30 return act.caller.String() + " " +
31 act.sent.String() + " sent, " +
32 act.returned.String() + " returned, at " +
33 act.time.Format("2006-01-02 3:04pm MST")
34}
35
36var latest [10]*activity
37```
38
39This is just maintaining a list of recent activity to this contract. Notice that the "latest" variable is defined "globally" within the context of the realm with path "gno.land/r/demo/banktest".
40
41This means that calls to functions defined within this package are encapsulated within this "data realm", where the data is mutated based on transactions that can potentially cross many realm and non-realm package boundaries (in the call stack).
42
43```go
44// Deposit will take the coins (to the realm's pkgaddr) or return them to user.
45func Deposit(returnDenom string, returnAmount int64) string {
46 std.AssertOriginCall()
47 caller := std.GetOrigCaller()
48 send := std.Coins{{returnDenom, returnAmount}}
49```
50
51This is the beginning of the definition of the contract function named "Deposit". `std.AssertOriginCall() asserts that this function was called by a gno transactional Message. The caller is the user who signed off on this transactional message. Send is the amount of deposit sent along with this message.
52
53```go
54 // record activity
55 act := &activity{
56 caller: caller,
57 sent: std.GetOrigSend(),
58 returned: send,
59 time: time.Now(),
60 }
61 for i := len(latest) - 2; i >= 0; i-- {
62 latest[i+1] = latest[i] // shift by +1.
63 }
64 latest[0] = act
65```
66
67Updating the "latest" array for viewing at gno.land/r/demo/banktest: (w/ trailing colon).
68
69```go
70 // return if any.
71 if returnAmount > 0 {
72```
73
74If the user requested the return of coins...
75
76```go
77 banker := std.GetBanker(std.BankerTypeOrigSend)
78```
79
80use a std.Banker instance to return any deposited coins to the original sender.
81
82```go
83 pkgaddr := std.GetOrigPkgAddr()
84 // TODO: use std.Coins constructors, this isn't generally safe.
85 banker.SendCoins(pkgaddr, caller, send)
86 return "returned!"
87```
88
89Notice that each realm package has an associated Cosmos address.
90
91Finally, the results are rendered via an ABCI query call when you visit [/r/demo/banktest:](/r/demo/banktest:).
92
93```go
94func Render(path string) string {
95 // get realm coins.
96 banker := std.GetBanker(std.BankerTypeReadonly)
97 coins := banker.GetCoins(std.GetOrigPkgAddr())
98
99 // render
100 res := ""
101 res += "## recent activity\n"
102 res += "\n"
103 for _, act := range latest {
104 if act == nil {
105 break
106 }
107 res += " * " + act.String() + "\n"
108 }
109 res += "\n"
110 res += "## total deposits\n"
111 res += coins.String()
112 return res
113}
114```
115
116You can call this contract yourself, by vistiing [/r/demo/banktest](/r/demo/banktest) and the [quickstart guide](/r/demo/boards:gnolang/4).
README.md
3.45 Kb ยท 116 lines