From 50da4a5f3f4e5c0164dced05311c5f33e3bea529 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 14 Apr 2025 18:35:00 +0200 Subject: [PATCH] update --- .gitattributes | 1 - .github/CODEOWNERS | 4 - .gitpod.yml | 58 ------ .idea/.gitignore | 8 + .idea/getting-started.iml | 9 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .vscode/settings.json | 3 - 001_gno_cli/README.md | 11 - 001_gno_cli/gno.mod | 1 - 001_gno_cli/hello.gno | 9 - 001_gno_cli/hello_test.gno | 11 - 002_gnokey/README.md | 108 ---------- 003_debug_gno_code/README.md | 51 ----- 003_debug_gno_code/gno.mod | 1 - 003_debug_gno_code/queue.gno | 15 -- 003_debug_gno_code/queue_test.gno | 17 -- 004_publishing_contracts/README.md | 258 ------------------------ 004_publishing_contracts/gno.mod | 5 - 004_publishing_contracts/guestbook.gno | 75 ------- 004_publishing_contracts/screenshot.png | Bin 14309 -> 0 bytes 005_blog/README.md | 19 -- 006_become_contributor/README.md | 15 -- LICENSE | 121 ----------- README.md | 21 +- z_misc/tools.go | 3 - 26 files changed, 32 insertions(+), 806 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .github/CODEOWNERS delete mode 100644 .gitpod.yml create mode 100644 .idea/.gitignore create mode 100644 .idea/getting-started.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml delete mode 100644 .vscode/settings.json delete mode 100644 001_gno_cli/README.md delete mode 100644 001_gno_cli/gno.mod delete mode 100644 001_gno_cli/hello.gno delete mode 100644 001_gno_cli/hello_test.gno delete mode 100644 002_gnokey/README.md delete mode 100644 003_debug_gno_code/README.md delete mode 100644 003_debug_gno_code/gno.mod delete mode 100644 003_debug_gno_code/queue.gno delete mode 100644 003_debug_gno_code/queue_test.gno delete mode 100644 004_publishing_contracts/README.md delete mode 100644 004_publishing_contracts/gno.mod delete mode 100644 004_publishing_contracts/guestbook.gno delete mode 100644 004_publishing_contracts/screenshot.png delete mode 100644 005_blog/README.md delete mode 100644 006_become_contributor/README.md delete mode 100644 LICENSE delete mode 100644 z_misc/tools.go diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 6635b0a..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.gno linguist-language=Go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 4d99b2e..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,4 +0,0 @@ -# CODEOWNERS: https://help.github.com/articles/about-codeowners/ - -# Primary repo maintainers. -* @gnolang/devrels @gnolang/tech-staff diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index f88619e..0000000 --- a/.gitpod.yml +++ /dev/null @@ -1,58 +0,0 @@ -# http://gitpod.io/#github.com/gnolang/getting-started-workshop - -additionalRepositories: - - url: https://github.com/gnolang/gno - checkoutLocation: gno - -tasks: - - name: Gnoland - before: cd ../gno/gno.land/ - init: go install ./cmd/gnoland - command: gnoland start - - - name: Gnoweb - before: cd ../gno/gno.land/ - init: go install ./cmd/gnoweb - command: gnoweb --bind=0.0.0.0:8888 - - - name: Deps - before: cd ../gno/misc/devdeps - init: | - make install - echo "Deps installed." - - - name: Gno CLI - init: | - go mod download - go install \ - github.com/gnolang/gno/gno.land/cmd/gnokey \ - github.com/gnolang/gno/gnovm/cmd/gno - command: gno --help - - #- name: faucet - # ... - -ports: - - name: gnoweb - description: "the Gno.land web server" - port: 8888 - onOpen: open-preview - - - name: "gnoland RPC" - description: "the RPC server, managed by tendermint2" - port: 36657 - onOpen: notify - -github: - prebuilds: - master: true - branches: true - pullRequests: true - pullRequestsFromForks: true - addCheck: true - addComment: true - addBadge: true - -vscode: - extensions: - - harry-hov.gno diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/getting-started.iml b/.idea/getting-started.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/getting-started.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d25014e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5ff7e9..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files.autoSave": "onWindowChange" -} diff --git a/001_gno_cli/README.md b/001_gno_cli/README.md deleted file mode 100644 index af8866c..0000000 --- a/001_gno_cli/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Getting Started with Gno CLI - -In this section, you will learn to use the `gno` CLI to write and test Gnolang packages. This part does not rely on a blockchain; instead, it operates solely on the GnoVM. - -## Steps - -* Use `gno --help` to explore available commands and options. -* Use `gno test .` to test your Gnolang packages. -* For additional features, explore `gno doc`, etc. - -Enjoy the journey of discovering and mastering the Gno CLI! diff --git a/001_gno_cli/gno.mod b/001_gno_cli/gno.mod deleted file mode 100644 index 7d15771..0000000 --- a/001_gno_cli/gno.mod +++ /dev/null @@ -1 +0,0 @@ -module gno.land/r/getting_started/001_gno_cli diff --git a/001_gno_cli/hello.gno b/001_gno_cli/hello.gno deleted file mode 100644 index a8626b3..0000000 --- a/001_gno_cli/hello.gno +++ /dev/null @@ -1,9 +0,0 @@ -package hello - -func Sum(a, b int) int { - return a + b -} - -func Greetings(name string) string { - return "Hello " + name + "!" -} diff --git a/001_gno_cli/hello_test.gno b/001_gno_cli/hello_test.gno deleted file mode 100644 index 452d59b..0000000 --- a/001_gno_cli/hello_test.gno +++ /dev/null @@ -1,11 +0,0 @@ -package hello - -import "testing" - -func TestSum(t *testing.T) { - got := Sum(1, 2) - expected := 3 - if got != expected { - t.Errorf("expected %d, got %d", expected, got) - } -} diff --git a/002_gnokey/README.md b/002_gnokey/README.md deleted file mode 100644 index 83ddb18..0000000 --- a/002_gnokey/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# Learn to Use Gnokey - -`gnokey` is the command line tool for interacting with a blockchain node. It -allows you to make blockchain transactions, publish new packages, and in general -do any operation with a remote or local blockchain node. - -We're going to start by importing a test wallet which has a lot of tokens -- -allowing you to freely play around. We'll then show you how you can create your -own wallet, although it will have no keys by default on the devnet -- but it can -be useful to play around with the online testnet. - -## Import the `test1` Wallet - -To import the `test1` wallet (10^13ugnot in genesis), use the following command: - -```console -gnokey add test1 --recover -``` - -Mnemonic: - -```console -source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast -``` - -Check: - -```console -gnokey list -``` - -
- Example... - -```console -$ gnokey list - -$ gnokey add test1 --recover -Enter a passphrase to encrypt your key to disk: -Repeat the passphrase: -Enter your bip39 mnemonic -source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast - -* test1 (local) - addr: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 pub: gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pq0skzdkmzu0r9h6gny6eg8c9dc303xrrudee6z4he4y7cs5rnjwmyf40yaj, path: - -$ gnokey list -0. test1 (local) - addr: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 pub: gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pq0skzdkmzu0r9h6gny6eg8c9dc303xrrudee6z4he4y7cs5rnjwmyf40yaj, path: -``` -
- -## Create a New Personal Wallet - -To create a new personal wallet, generate your 24 keywords with the command: - -```console -gnokey generate -``` - -Then follow the instructions for `test1`, but use your chosen name, e.g., `bob`. - -
- Example... - -```console -$ gnokey generate -meat middle doctor gasp axis drastic flower song test public hire title ivory walnut pledge violin mechanic hedgehog rapid satisfy measure autumn front blind - -$ gnokey add bob --recover -Enter a passphrase to encrypt your key to disk: -Repeat the passphrase: -Enter your bip39 mnemonic -meat middle doctor gasp axis drastic flower song test public hire title ivory walnut pledge violin mechanic hedgehog rapid satisfy measure autumn front blind - -* bob (local) - addr: g1h5tap94s8k0dhwhkldf39vavucvnjhrhepmt8a pub: gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pqdzdqdzjre7nfvtd7ge3gsenxsdf0ww2fcazt957q76glapsrxgeg774qj2, path: - -$ gnokey list -0. bob (local) - addr: g1h5tap94s8k0dhwhkldf39vavucvnjhrhepmt8a pub: gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pqdzdqdzjre7nfvtd7ge3gsenxsdf0ww2fcazt957q76glapsrxgeg774qj2, path: -1. test1 (local) - addr: g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 pub: gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pq0skzdkmzu0r9h6gny6eg8c9dc303xrrudee6z4he4y7cs5rnjwmyf40yaj, path: -``` -
- -## Interact with the `r/demo/boards` Realm - -Now that we have set up an account, let's try interacting with a smart contract. - -```console -$ gnokey maketx call \ - -pkgpath "gno.land/r/demo/boards" \ - -func "CreateThread" \ - -gas-fee 1000000ugnot \ - -gas-wanted 2000000 \ - -send "100000000ugnot" \ - -broadcast \ - -chainid "dev" \ - -args "1" \ - -args "Hello world\!" \ - -args "Just fooling around with creating a new thread on r/demo/boards." \ - -remote "127.0.0.1:26657" test1 -Enter password. -(7 gno.land/r/demo/boards.PostID) -OK! -GAS WANTED: 2000000 -GAS USED: 1043320 -``` - -If you click on `r/demo/boards` from the browser in the top-right corner of -Gitpod, and browse to testboard, you should now be able to see a "Hello world!" -post with the test1 address at the bottom of the page. diff --git a/003_debug_gno_code/README.md b/003_debug_gno_code/README.md deleted file mode 100644 index 8338fc7..0000000 --- a/003_debug_gno_code/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Debugging Gno code - -In this section, you will learn to debug your Gno contract. As contracts aren't -modifiable, it is crucial to debug them properly before their publication to -the blockchain. - -Debugging Gno code functions in many ways as in Go; -the biggest tool at our disposal are test files. These are identified -as source files whose names end with `_test.go`. Every function of -the kind `func TestXxx(t *testing.T)` is automatically added as a test, -run when using `gno test`. If the function calls `t.Errorf`, then it is -considered failed. - -- `queue.gno`, in this tutorial's directory `003-debug-gno-code`, is a source file containing 2 stub functions `Push` and `Pop`. Your goal in this tutorial is to implement them correctly and see the tests succeed. -- `queue_test.gno` contains a test that checks the behavior of `Pop` and `Push`. - If you implement them correctly, running `gno test` will succeed without errors. - -## Steps - -- Run the test: -``` -$ gno test . -verbose -``` -The test will fail, because `Pop` and `Push` are currently not -implemented -- if you open the `queue.gno` file, you will see -that they just contain two `// TODO` comments. - -- Implement `Pop` and `Push`. These need to implement a - FIFO (First In, First Out) queue -- so the last element added - using `Push` will be the first one to be removed using `Pop`. -- Run the test again until it succeeds - -
- Solution (only if you're stuck!) - -```go -func Push(s string) { - q = append(q, s) -} - -func Pop() string { - if len(q) == 0 { - return "" - } - s := q[0] - q = q[1:] - return s -} -``` - -
diff --git a/003_debug_gno_code/gno.mod b/003_debug_gno_code/gno.mod deleted file mode 100644 index 2fe0baf..0000000 --- a/003_debug_gno_code/gno.mod +++ /dev/null @@ -1 +0,0 @@ -module gno.land/r/getting_started/003_debug_gno_code diff --git a/003_debug_gno_code/queue.gno b/003_debug_gno_code/queue.gno deleted file mode 100644 index 4aefcdd..0000000 --- a/003_debug_gno_code/queue.gno +++ /dev/null @@ -1,15 +0,0 @@ -package queue - -var q []string - -// Push appends s to q. -func Push(s string) { - // TODO -} - -// Pop removes the first element of q and returns it. -// If q is empty, Pop returns an empty string. -func Pop() string { - // TODO - return "" -} diff --git a/003_debug_gno_code/queue_test.gno b/003_debug_gno_code/queue_test.gno deleted file mode 100644 index a3d5c6f..0000000 --- a/003_debug_gno_code/queue_test.gno +++ /dev/null @@ -1,17 +0,0 @@ -package queue - -import "testing" - -func TestQueue(t *testing.T) { - // Push 2 items - Push("alice") - Push("bob") - // Call Pop() 3 times - // Third time should return an empty string because the queue is empty - for i, expected := range []string{"alice", "bob", ""} { - res := Pop() - if res != expected { - t.Errorf("Pop()#%d want %q, got %q", i, expected, res) - } - } -} diff --git a/004_publishing_contracts/README.md b/004_publishing_contracts/README.md deleted file mode 100644 index f2e68a0..0000000 --- a/004_publishing_contracts/README.md +++ /dev/null @@ -1,258 +0,0 @@ -# Publishing contracts - -Now that you know how to write programs and debug gno code, let's get you started -publishing some smart contracts. - -In `guestbook.gno`, you can see a simple application for a guestbook. If you did -not already set up your test1 wallet, it's a good time to do so: [follow -the instructions from the second example](../002-gnokey/README.md). - -The advantage of using the `test1` key instead of your own key is that it has, -at genesis, a large number of tokens which can help us run transactions straight -off the bat. - -From this directory (use the `cd` command in the shell to navigate -`004-publish-contracts`), run the following command: - -``` -gnokey maketx addpkg \ - --gas-wanted 10000000 \ - --gas-fee 1ugnot \ - --pkgpath gno.land/r/demo/guestbook \ - --pkgdir . \ - --broadcast \ - test1 -``` - -**Note:** if you need to re-publish the contract, you will get an error if you -run the same command again, as for the time being publishing packages is -permanent and they cannot be modified. So, if you modified the contract, simply -change the `pkgpath` argument slightly (ie. `gno.land/r/demo/guestbook2`). - -## Browsing the contract - -In the source code, there is a `Render` function. This enables us to browse the -smart contract through the `gnoweb` HTTP frontend. - -From the simple browser in your Gitpod, browse to the path `/r/demo/guestbook` -(appending it to the Gitpod URL - so something like -`https://8888-gnolang-gettingstarted-lnw0x71frja.ws-eu102.gitpod.io/r/demo/guestbook`). -You will see a markdown rendering of the website, which works by executing the Render() -function. - -As expected, there will be one single signature on the guestbook -- the one -defined in `var signatures`. Let's fix that and add a new one! - -## Adding a new signature - -If you click on the `[help]` link in the header, on the right, you -will also be able to see a list of the exported functions of the realm, and -instructions on how to execute them using `gnokey`. - -By modifying the fields, you can interactively set up your `gnokey` command, and -make it do whatever you want it to. - -![A screenshot of a simple configuration of gnokey, that we will use -later.](./screenshot.png) - -Let's run that command: - -``` -gnokey maketx call \ - -pkgpath "gno.land/r/demo/guestbook" \ - -func "Sign" \ - -gas-fee 1000000ugnot \ - -gas-wanted 2000000 \ - -send "" \ - -broadcast \ - -chainid "dev" \ - -args "Hello world\! And hello, **bold**\!" \ - -remote "127.0.0.1:26657" \ - test1 -``` - -The transaction should succeed, and if you browse again to the homepage of the -realm you should see your new post with your address. Ta-da! :tada: - -## The magic of realms - -We have glossed over an important concept of Gno for the sake of the tutorial: -how global variables work in realms. You may have noticed that in the source -code we declared a global variable, which contained the first signature: - -```go -var signatures = []Signature{ - { - Message: "You've reached the end of the guestbook!", - Address: "", - Time: time.Date(2023, time.January, 1, 12, 0, 0, 0, time.UTC), - }, -} -``` - -This shows up when we browse the realm from the web, and all is good here. -However, after we call `Sign`, it stores the new signature in the global -variable, and suddenly -- poof! -- the signature appears in the guestbook. - -```go - // append new signature -- at the top of the list - signatures = append([]Signature{{ - Message: message, - Address: caller, - Time: time.Now(), - }}, signatures...) -``` - -This is the magic of Gno realms -- they are **stateful.** This means that when -in a transaction you change a global variable, or any data stored within it, the -new data is automagically stored and persisted on the blockchain. - -Because we're running in a blockchain context, as opposed to Go we can't have -things like network access, or access to the filesystem, or using -cryptographically random functions. These are all **non-deterministic,** meaning -that if you attempt to run the code twice, or on different machines, it may lead -to different results. Gno code, in contracts, like all other smart contracts, -must be **deterministic** and always have the same results if it's given the -same starting context -- which is why we provide global variables as a solution -for storing data. - -### Deterministic time - -The careful observer may note that `time.Now()` is not a deterministic value, as by -definition it is always changing and "should" be different each time the program -is executed. However, to enable the use of time.Now() in blockchain, this will -actually represent the _block time_. - -In a blockchain, a new "block" is created after a given amount of time. This -will roughly match the current time; but note the value does not change during -the execution of the program, and as such `time.Now()` cannot be used to -benchmark a program -- it is just a rough idea of what time the transaction is -executed. - -### The difference between realms and packages - -As you've learned, realms have the distinctive feature of being able to persist -their global variables. The underlying idea here is that realms are end-user -smart contracts; which is why they also support the `Render()` function for -viewing their data on the web. - -In `guestbook.gno`, however, we make an import of package -`gno.land/p/demo/ufmt`. This is an example of a _package_ (as opposed to a -_realm_) -- it is distinct from a realm because its import path starts with -`gno.land/p/` instead of `gno.land/r/`.[^1] - -Packages behave like normal Go packages, or similar concepts of other -programming languages: they are reusable pieces of code which are meant as -"building blocks" to build complex software. They don't persist any data, nor -their functions can be executed as smart contracts. - -## Keep going - -There are two more challenges for you in `guestbook.gno`: you can find them in -the `TODO` comments. - -The first one is to prevent a user from signing the guestbook more than once, -aborting the transaction entirely. In Gno, you can abort transactions by using -the `panic()` function. - -
- Sample solution (only if you're stuck!) - -```go -for _, sig := range signatures { - if sig.Address == caller { - panic("you have already signed the guestbook!") - } -} -``` - -
- -The second one is to use the `gno.land/r/demo/users` realm to render usernames. -The `users` realm is a "username registry" which is used in -other example realms, like [`microblog`](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo/microblog), -[`boards`](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo/boards) -and [`groups`](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo/groups). -You can inspect it and register yourself as a user of the realm. - -We can make our guestbook nicer by referring to users using their username -instead of their address... - -Here's a sample command to register a user (note the `--send` argument -- we use -this to register without being "invited"): - -``` -gnokey maketx call \ - -pkgpath "gno.land/r/demo/users" \ - -func "Register" \ - -gas-fee 1000000ugnot \ - -gas-wanted 2000000 \ - -send "200000000ugnot" \ - -broadcast \ - -chainid "dev" \ - -args "" -args "torvalds" -args "https://github.com/torvalds" \ - -remote "127.0.0.1:26657" test1 -``` - -
- Hint - -To call other realms in Gno, we simply have to import them at the top of the -file in the `import` statement. After doing that, you can use the function -`users.GetUserByAddress` to see if there is a matching User. - -
- -
- Sample solution (only if you're stuck!) - -```go -// add import: "gno.land/r/demo/users" - -func Render(string) string { - b := new(strings.Builder) - // gnoweb, which is the HTTP frontend we're using, will render the content we - // pass to it as markdown. - b.WriteString("# Guestbook\n\n") - for _, sig := range signatures { - a := string(sig.Address) - if a == "" { - a = "anonymous coward" - } else if u := users.GetUserByAddress(sig.Address); u != nil { - a = ufmt.Sprintf("[@%s](/r/demo/users:%s)", - u.Name(), u.Name()) - } - // We currently don't have a full fmt package; we have "ufmt" to do basic formatting. - // See `gno doc ufmt` for more information. - // - // If you are unfamiliar with Go time formatting, it is done by writing the way you'd - // format a reference time. See `gno doc time.Layout` for more information. - b.WriteString(ufmt.Sprintf( - "%s\n\n_written by %s at %s_\n\n----\n\n", - sig.Message, a, sig.Time.Format("2006-01-02"), - )) - } - return b.String() -} -``` - -
- -## Recap - -1. By using the `gnokey maketx addpkg`, we can add a new package or realm to the - blockchain. -2. Packages are reusable "building blocks" of code. Realms are "special - packages" which: - - Can persist state in their global variables - - Can have their functions called as smart contracts, using `gnokey` - - Can be rendered through the web frontend, using the special `Render` function -3. Using the `[help]` page of gnoweb, we can construct transactions to smart - contracts we've created. -4. All Gno code must be deterministic and run exactly the same independent of - the machine. We are still allowed to use `time.Now()` -- however that will - actually return the block time instead of the machine's clock time. -5. We can make calls to other realms with their state by simply importing their - path in our Gno code. - -[^1]: at the moment, all code uploaded to the chain must have an import path starting with either of the two. diff --git a/004_publishing_contracts/gno.mod b/004_publishing_contracts/gno.mod deleted file mode 100644 index 2fa4be4..0000000 --- a/004_publishing_contracts/gno.mod +++ /dev/null @@ -1,5 +0,0 @@ -module gno.land/r/getting_started/004_publishing_contracts - -require ( - gno.land/p/demo/ufmt v0.0.0-latest -) diff --git a/004_publishing_contracts/guestbook.gno b/004_publishing_contracts/guestbook.gno deleted file mode 100644 index 6466da7..0000000 --- a/004_publishing_contracts/guestbook.gno +++ /dev/null @@ -1,75 +0,0 @@ -// Realm guestbook is a smart contract to register presences at a workshop. -// Participants to the workshop can add their own signature by calling the [Sign] -// contract. -package guestbook - -import ( - "std" - "strings" - "time" - - "gno.land/p/demo/ufmt" -) - -type Signature struct { - Message string - Address std.Address - Time time.Time -} - -var signatures = []Signature{ - { - Message: "You've reached the end of the guestbook!", - Address: "", - Time: time.Date(2023, time.January, 1, 12, 0, 0, 0, time.UTC), - }, -} - -// Sign adds a new signature to the guestbook -func Sign(message string) { - // AssertOriginCall makes it possible to call Sign only as a transaction - ie. - // it cannot be executed as a function, or called from other realms. - std.AssertOriginCall() - // caller, type std.Address, is the address of who has called this contract. - caller := std.GetOrigCaller() - - // TODO: make sure caller hasn't signed the guestbook already - - // append new signature -- at the top of the list - signatures = append([]Signature{{ - Message: message, - Address: caller, - Time: time.Now(), - }}, signatures...) -} - -// Render is called when running the realm through gnoweb, and allows to render -// the realm's internal data, without the possibility of changing it. -// -// Render accepts a string, which is a "request path" -- similar to an HTTP -// request. We will be further exploring this at a later time, for now the -// argument is ignored. -func Render(string) string { - b := new(strings.Builder) - // gnoweb, which is the HTTP frontend we're using, will render the content we - // pass to it as markdown. - b.WriteString("# Guestbook\n\n") - for _, sig := range signatures { - a := string(sig.Address) - if a == "" { - a = "anonymous coward" - } - // We currently don't have a full fmt package; we have "ufmt" to do basic formatting. - // See `gno doc ufmt` for more information. - // - // If you are unfamiliar with Go time formatting, it is done by writing the way you'd - // format a reference time. See `gno doc time.Layout` for more information. - b.WriteString(ufmt.Sprintf( - "%s\n\n_written by %s on %s_\n\n----\n\n", - sig.Message, a, sig.Time.Format("2006-01-02"), - )) - - // TODO: resolve sig.Address to a username, by using the r/demo/users realm. - } - return b.String() -} diff --git a/004_publishing_contracts/screenshot.png b/004_publishing_contracts/screenshot.png deleted file mode 100644 index f5c3dbd4bb87d6a9f219817214e9dc7e795bee56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14309 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 Ee|yXQLjV8( diff --git a/005_blog/README.md b/005_blog/README.md deleted file mode 100644 index 935eab8..0000000 --- a/005_blog/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Building Social Apps on Gno - -## Overview - -Congratulations on completing the previous steps! Now, let's take on a more challenging task. - -One of Gno's standout features is how it simplifies building social apps compared to other ecosystems. Social apps focus on managing more complex objects, involving various types, recursive pointers, and so on, instead of just arrays of balances like many DeFi apps. - -Let's explore some existing apps as examples. If you attend a physical workshop, feel free to ask questions and discuss with the organizers. - -## Resources - -Here are some example apps to get you started: - -- [Boards](https://github.com/gnolang/gno/tree/master/examples/gno.land/r/demo/boards) -- [Microblog](https://github.com/gnolang/gno/tree/master/examples/gno.land/r/demo/microblog) -- [Blog](https://github.com/gnolang/gno/tree/master/examples/gno.land/r/gnoland/blog) - -_Organizers Note: We can make this exercice better by bootstrapping a series of .gno files, with a Render func and commands calling `gno test --update-golden-tests`._ diff --git a/006_become_contributor/README.md b/006_become_contributor/README.md deleted file mode 100644 index 1e50dda..0000000 --- a/006_become_contributor/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Become a Contributor - -Welcome to the Gno community! This series of exercises has introduced you to Gno, but the real excitement lies ahead as we build Gno together, hand in hand with our community. - -With our innovative [Proof of Contribution](https://github.com/gnolang/gno/issues/918) consensus mechanism, we are creating an ecosystem that truly belongs to its contributors. - -## Next Steps - -- Check out the main repository at https://github.com/gnolang/gno. You can get involved by looking for existing issues to work on or proposing improvements that haven't been requested yet. - -- Participate in the thrilling [Game of Realms](https://github.com/gnolang/gno/issues/390) online competition, where you can contribute and earn prizes in ATOM. - -- Join our vibrant community on various platforms such as Twitter, Discord, and Reddit. Engage in discussions and share your ideas with like-minded individuals. - -Together, we'll shape the future of Gno and make a lasting impact on the blockchain landscape. We look forward to collaborating with you and building something truly special! diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0e259d4..0000000 --- a/LICENSE +++ /dev/null @@ -1,121 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. diff --git a/README.md b/README.md index a0a50b0..7c01c84 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Welcome to the world of Gno! Through this repository, you can effortlessly embark on a journey to write your first Gno realm -- otherwise known as a smart contract. -Before you begin, we highly recommend exploring [Gno By Example](https://gno-by-example.com) to familiarize yourself with Gno's foundational concepts. +Before you begin, we highly recommend exploring the [Official Documentation](https://docs.gno.land) to familiarize yourself with Gno's foundational concepts. ## Suggested Discovery Plan @@ -14,25 +14,6 @@ Before you begin, we highly recommend exploring [Gno By Example](https://gno-by- 6. Start building more complex dApps, utilizing realms (`/r/...`) and pure packages (`/p/...`) you create or those crafted by the community. Leverage the `Render()` function for smooth interactions. 7. Experiment with creating web frontends or new clients to engage with the chain and your contracts. -## Using Gitpod - -Gitpod simplifies the setup by providing a `gnoland` node, a `gnoweb` server, and a pre-configured terminal with the `gno` CLI. - -1. Just click the button below. -2. Start hacking! - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/new/#https://github.com/gnolang/getting-started) - -## Fork and Hack - -1. Install `gno` from https://github.com/gnolang/gno and set up your local environment. -2. Fork this repo. -3. Start hacking! - -## Gno IDE - -_Coming soon_ - ## Resources - Gno By Example: https://gno-by-example.com diff --git a/z_misc/tools.go b/z_misc/tools.go deleted file mode 100644 index b2ac548..0000000 --- a/z_misc/tools.go +++ /dev/null @@ -1,3 +0,0 @@ -package tools - -import _ "github.com/gnolang/gno/gnovm/cmd/gno"