gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
844 stars 344 forks source link

Contract call on Gnolang #490

Closed go7066 closed 1 year ago

go7066 commented 1 year ago

I am a Teritori team member and we have built multisig (project name called gnosig) in Gnolang as part of our contribution to Gnoland ecosystem - voting and proposals posting part are done. The problem is the contract call part where multisig should execute once it's approved. Is there any interface to call a contract something like this on the contract side?

Contract(contractAddress).Function(Params...)

There's no documentation written about this anywhere.

moul commented 1 year ago

It's like standard go, you should do somethine like this:

import "gno.land/r/name/foobar"

func Baz() {
    foobar.Method(params...)
}
go7066 commented 1 year ago

It's like standard go, you should do somethine like this:

import "gno.land/r/name/foobar"

func Baz() {
    foobar.Method(params...)
}

This used to report issue locally when I run test. How to test if it works locally? Is there any example project doing contract calls?

Something like this

panic: unknown import path gno.land/r/board [recovered]
    panic: ./r/multisig/multisig.gno:1: unknown import path gno.land/r/board

goroutine 1 [running]:
github.com/gnolang/gno/pkgs/gnolang.predefineNow.func1()

/gno/pkgs/gnolang/preprocess.go:2812 +0x317
panic({0x168c9a0, 0xc000368c00})
    /usr/local/go/src/runtime/panic.go:838 +0x207
github.com/gnolang/gno/pkgs/gnolang.tryPredefine({0x187d040, 0xc000344360}, {0x187a7a8, 0xc0004182c0}, {0x18793c8, 0xc00030cd00?})

/gno/pkgs/gnolang/preprocess.go:2927 +0x12b9
github.com/gnolang/gno/pkgs/gnolang.predefineNow2({0x187d040, 0xc000344360}, {0x187a7a8, 0xc0004182c0}, {0x18793c8?, 0xc00030cd00?}, 0x203000?)

/gno/pkgs/gnolang/preprocess.go:2828 +0x13a
github.com/gnolang/gno/pkgs/gnolang.predefineNow({0x187d040, 0xc000344360}, {0x187a7a8, 0xc0004182c0}, {0x18793c8, 0xc00030cd00})

/gno/pkgs/gnolang/preprocess.go:2817 +0x149
github.com/gnolang/gno/pkgs/gnolang.PredefineFileSet({0x187d040, 0xc000344360}, 0xc000432840, 0xc000311c38)

/gno/pkgs/gnolang/preprocess.go:38 +0x6ea
github.com/gnolang/gno/pkgs/gnolang.(*Machine).runFiles(0xc0005998c0, {0xc00011a9e8, 0x1, 0x1})

/gno/pkgs/gnolang/machine.go:367 +0x276
github.com/gnolang/gno/pkgs/gnolang.(*Machine).RunFiles(...)
moul commented 1 year ago

The current version of gnodev requires to have the sources available locally. In the future, it will automatically support fetching missing dependencies from the chain.

It also requires having the import path available from the -root-dir flag. gno.land/r/board should be available at $rootdir/gno.land/r/board/*.gno. In the future, we'll support a kind of go.mod file support.

Here is an example of repo that uses go.mod and Makefile to support imports: https://github.com/moul/gno-basics/blob/main/005-import/contract.gno.

moul commented 1 year ago

Also, take care, the new import path for boards is gno.land/r/demo/boards (https://github.com/gnolang/gno/tree/master/examples/gno.land/r/demo/boards)

go7066 commented 1 year ago

Okay thanks for the direction, will follow the guidance

go7066 commented 1 year ago

Checked that boards exists on gno directory locally, imported and executed.

import (
    "gno.land/r/boards"
)

...

    // Execute an approved tx
    boards.CreateBoard("new board")

Getting following issue when running the test.

=== RUN   TestExecute
panic: invalid non-origin call

goroutine 1 [running]:
github.com/gnolang/gno/tests.testPackageInjector.func1(0xc00059db00?)
    <path-to>/gno/tests/imports.go:453 +0x3b
github.com/gnolang/gno/pkgs/gnolang.(*Machine).doOpCallNativeBody(...)
    <path-to>/gno/pkgs/gnolang/op_call.go:162
github.com/gnolang/gno/pkgs/gnolang.(*Machine).Run(0xc00059db00)
    <path-to>/gno/pkgs/gnolang/machine.go:979 +0x1cc
github.com/gnolang/gno/pkgs/gnolang.(*Machine).Eval(0xc00059db00, {0x1877e38, 0xc00c485f20})
    <path-to>/gno/pkgs/gnolang/machine.go:571 +0x565
main.runTestFiles(0x1?, {0x187d040?, 0xc0001c2240?}, 0x17621de?, 0xc00000f098, {0xc0002be940, 0x8}, 0x1, {0x0, 0x0})
    <path-to>/gno/cmd/gnodev/test.go:277 +0x3fe
main.gnoTestPkg(0x168c9a0?, {0xc0002be720, 0xc}, {0xc00021ff00?, 0x1, 0x168c9a0?}, {0x0, 0x0, 0x8?}, {0x1, ...})
    <path-to>/gno/cmd/gnodev/test.go:184 +0x28a
main.testApp(0x1718e00?, {0xc0000321a0, 0x1, 0x4}, {0x1718e00?, 0xc0000ef940?})
    <path-to>/gno/cmd/gnodev/test.go:133 +0xe51
github.com/gnolang/gno/pkgs/command.(*Command).Run(0xc000032d20, 0x17ac848, {0xc0000321a0?, 0x57d4da8?, 0x203000?}, {0x1718e00, 0x1c95e80})
    <path-to>/gno/pkgs/command/command.go:64 +0x2e4
main.runMain(0xc0000021a0?, {0xc000207f70?, 0x1007659?}, {0xc000032190, 0x5, 0x5})
    <path-to>/gno/cmd/gnodev/main.go:60 +0x42c
main.main()
    <path-to>/gno/cmd/gnodev/main.go:14 +0x6f

How stores are managed on gno contracts? (It's the biggest question on my side for this kind of contract import)

go7066 commented 1 year ago

Is it fine to not set any contract address here? (Since it's a contract call) Any document or examples doing such stuff?

moul commented 1 year ago

Hey @go7066, I moved the issue on the main repo.

moul commented 1 year ago

I suggest you look at the examples folder on this repo.

If you think that some documentation may be improved; feel free to do it, it could count for #408.

go7066 commented 1 year ago

@moul couldn't find any contract call within a contract on examples folder.

go7066 commented 1 year ago

Hey @go7066, I moved the issue on the main repo.

Can you confirm which issue ticket is created by closing this issue? (Which one is the main repo for the issue ticket?

moul commented 1 year ago

Please, read #757

tbruyelle commented 1 year ago

image

@go7066 the reason why you can't call boards.CreateBoard() from an other contract is because the function requires to be called directly by the user. This is because at the beginning of the function std.AssertOriginCall() is invoked. std.AssertOriginCall panics if the caller is an other contract.

So it is by design, you can't do anything about it.

Other functions that doesn't invoke std.AssertOriginCall() can be called from other contracts without issue.