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