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).