Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.cartesi
examples/go.mod
examples/go.sum
examples/example.go
example-apps/go.mod
example-apps/go.sum
example-apps/app.go
example-apps/app
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Cartesi Rollups GO high level framework

```
This works for Cartesi Rollups Node version 1.5.x (cartesi cli version 0.16.x)
This works for Cartesi Rollups Node version 2.0.x (cartesi cli version ?.?.x)
```

Create cartesi rolllups DApp with codes like:
Create cartesi rolllups applications with simple lines of code like:

```go
package main
Expand All @@ -31,20 +31,33 @@ func main() {
}
```

Check the [examples](examples) for more use cases.
Check the [examples](example-apps/apps-src) for more use cases.

You will need [cartesi cli](https://github.com/cartesi/cli) to create and run the example, and [curl](https://curl.se/) to interact with the dapp.
You will need [cartesi cli](https://github.com/cartesi/cli) to create and run the example, and [curl](https://curl.se/) to interact with the app.

To run an example

```shell
cd examples
rm -rf example.go
ln -sr example1_rollups_helpers.go example.go
cd example-apps
rm -rf app.go
ln -sr ln -sr apps-src/example11_wallet.go app.go
```

The you can build and run with

```shell
cartesi build
cartesi run
```

Optionally, you can compile directly in the host and run with [nonodo](https://github.com/Calindra/nonodo/) and the [cartesi machine](https://github.com/cartesi/machine-emulator) (you'll also need `riscv64-linux-gnu-gcc`). First start nonodo:


```shell
GOOS=linux GOARCH=riscv64 CGO_ENABLED=1 CC=riscv64-linux-gnu-gcc go build -o app app.go
nonodo -- cartesi-machine --env=ROLLUP_HTTP_SERVER_URL=http://10.0.2.2:5004 --network --flash-drive=label:root,filename:.cartesi/image.ext2 --volume=.:/mnt --workdir=/mnt -- ./app
```

You can send inputs with (account and private key of anvil test accounts)

```shell
Expand Down
14 changes: 7 additions & 7 deletions examples/Dockerfile → example-apps/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ ENV CGO_ENABLED=1
ENV CC=riscv64-linux-gnu-gcc
ENV PATH=/usr/local/go/bin:${PATH}

COPY example.go .
COPY app.go .

RUN go mod init dapp && \
RUN go mod init app && \
go mod tidy && \
go build -o dapp example.go
go build -o app app.go

# runtime stage: produces final image that will be executed
FROM --platform=linux/riscv64 riscv64/ubuntu:22.04
Expand All @@ -47,15 +47,15 @@ apt-get update
apt-get install -y --no-install-recommends \
busybox-static=1:1.30.1-7ubuntu3
rm -rf /var/lib/apt/lists/* /var/log/* /var/cache/*
useradd --create-home --user-group dapp
useradd --create-home --user-group app
EOF

ENV PATH="/opt/cartesi/bin:${PATH}"

WORKDIR /opt/cartesi/dapp
COPY --from=build-stage /opt/build/dapp .
WORKDIR /opt/cartesi/app
COPY app .

ENV ROLLUP_HTTP_SERVER_URL="http://127.0.0.1:5004"

ENTRYPOINT ["rollup-init"]
CMD ["/opt/cartesi/dapp/dapp"]
CMD ["/opt/cartesi/app/app"]
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package main

import (
"fmt"
"log"
"os"
"math/big"
"encoding/json"

"github.com/prototyp3-dev/go-rollups/rollups"
"github.com/prototyp3-dev/go-rollups/handler/abi"
"github.com/prototyp3-dev/go-rollups/wallet"
"encoding/json"
"fmt"
"log"
"math/big"
"os"

"github.com/prototyp3-dev/go-rollups/handler/abi"
"github.com/prototyp3-dev/go-rollups/rollups"
"github.com/prototyp3-dev/go-rollups/wallet"
)

var infolog = log.New(os.Stderr, "[ info ] ", log.Lshortfile)
Expand Down Expand Up @@ -145,7 +145,7 @@ func main() {
myApp.dappWallet = wallet.NewWalletApp();
myApp.dappWallet.SetAbiHandler(appHandler)

// setups the dapp relay and fixed portal deposit routes
// setups fixed portal deposit routes
// overrides any fixed address handler
// and extra routes to control assets
myApp.dappWallet.SetupRoutes([]wallet.WalletRoute{
Expand All @@ -154,9 +154,9 @@ func main() {
wallet.TransferEtherAdvanceRoute,
wallet.BalanceInspectRoute,wallet.BalanceUriInspectRoute})

appHandler.HandleAdvanceRoute(abihandler.NewHeaderCodec("dapp","fee",[]string{}), myApp.PayFee)
appHandler.HandleFixedAddressAdvance(abihandler.Address2Hex(developerAddress),abihandler.NewHeaderCodec("dapp","changeFee",[]string{"uint256 fee"}), myApp.ChangeFee)
appHandler.HandleInspectRoute(abihandler.NewHeaderCodec("dapp","fee",[]string{"address address"}), myApp.GetFee)
appHandler.HandleAdvanceRoute(abihandler.NewHeaderCodec("dapp.fee",[]string{}), myApp.PayFee)
appHandler.HandleFixedAddressAdvance(abihandler.Address2Hex(developerAddress),abihandler.NewHeaderCodec("dapp.changeFee",[]string{"uint256 fee"}), myApp.ChangeFee)
appHandler.HandleInspectRoute(abihandler.NewHeaderCodec("dapp.fee",[]string{"address address"}), myApp.GetFee)
myApp.dappWallet.UriHandler().HandleInspectRoute("/fee/:address", myApp.GetFeeUri)

appHandler.HandleDefault(myApp.HandleWrongWay)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package main

import (
"encoding/json"
"io/ioutil"
"io"
"strconv"
"fmt"
"log"
Expand Down Expand Up @@ -64,6 +64,10 @@ func Handler(response *rollups.FinishResponse) error {
}

func main() {
if rollups.GetRollupServer() == "" {
rollups.SetRollupServer(os.Getenv("ROLLUP_HTTP_SERVER_URL"))
}

finish := rollups.Finish{Status: "accept"}

for true {
Expand All @@ -78,7 +82,7 @@ func main() {
infolog.Println("No pending rollup request, trying again")
} else {

resBody, err := ioutil.ReadAll(res.Body)
resBody, err := io.ReadAll(res.Body)
if err != nil {
errlog.Panicln("Error: could not read response body: ", err)
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func HandleAdvance(metadata *rollups.Metadata, payloadHex string) error {
return fmt.Errorf("HandleAdvance: error making http request: %s", err)
}

body, err := ioutil.ReadAll(res.Body)
body, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("HandleAdvance: could not read response body: %s", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

var infolog = log.New(os.Stderr, "[ info ] ", log.Lshortfile)

var relayMessage string
var operatorMessage string

func GenericHandler(payloadHex string) error {
payload, err := rollups.Hex2Str(payloadHex)
Expand All @@ -20,7 +20,7 @@ func GenericHandler(payloadHex string) error {
}
infolog.Println("Generic request payload:", payload)

report := rollups.Report{Payload: rollups.Str2Hex("Generic " + payload + relayMessage)}
report := rollups.Report{Payload: rollups.Str2Hex("Generic " + payload + operatorMessage)}
_, err = rollups.SendReport(&report)
if err != nil {
return fmt.Errorf("GenericHandler: error making http request: %s", err)
Expand All @@ -41,11 +41,15 @@ func HandleFixed(metadata *rollups.Metadata, payloadHex string) error {
}


func HandleRelay(metadata *rollups.Metadata, payloadHex string) error {
infolog.Println("Hey, I know this address, sender is",metadata.MsgSender,"and the my address is", payloadHex)
relayMessage = fmt.Sprint(" and the dapp address is ",payloadHex)
report := rollups.Report{Payload: rollups.Str2Hex("Set address relay")}
_, err := rollups.SendReport(&report)
func HandleOperator(metadata *rollups.Metadata, payloadHex string) error {
infolog.Println("Hey, I know this address, sender is",metadata.MsgSender,"and the message is", payloadHex)
payloadStr, err := rollups.Hex2Str(payloadHex)
if err != nil {
return fmt.Errorf("HandleOperator: hex error decoding payload:", err)
}
operatorMessage = fmt.Sprint(" and the message is ",payloadStr)
report := rollups.Report{Payload: rollups.Str2Hex("Set operator message")}
_, err = rollups.SendReport(&report)
if err != nil {
return fmt.Errorf("HandleFixed: error making http request: %s", err)
}
Expand All @@ -57,9 +61,11 @@ func HandleRelay(metadata *rollups.Metadata, payloadHex string) error {
func main() {
handler.InitializeRollupsAddresses("localhost")

operator := "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

handler.HandleDefault(GenericHandler)
handler.HandleRollupsFixedAddresses(HandleFixed)
handler.HandleFixedAddress(handler.RollupsAddresses.DappAddressRelay, HandleRelay)
handler.HandleFixedAddress(operator, HandleOperator)

err := handler.RunDebug()
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (

var infolog = log.New(os.Stderr, "[ info ] ", log.Lshortfile)

var dappAddress string

func HandleEther(metadata *rollups.Metadata, payloadHex string) error {
deposit, err := rollups.DecodeEtherDeposit(payloadHex)
if err != nil {
Expand All @@ -23,26 +21,22 @@ func HandleEther(metadata *rollups.Metadata, payloadHex string) error {

infolog.Println("Received",new(big.Float).Quo(new(big.Float).SetInt(deposit.Amount),big.NewFloat(1e18)),"native token deposit from",deposit.Depositor,"data:",string(deposit.Data))

if dappAddress != "" {
voucher := rollups.EtherWithdralVoucher(dappAddress, deposit.Depositor, deposit.Amount)
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleEther: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
} else {
infolog.Println("Can't generate voucher as there is no dapp address configured")
voucher := rollups.EtherWithdralVoucher(deposit.Depositor, deposit.Amount)
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleEther: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
return nil
}

func HandleErc20(metadata *rollups.Metadata, payloadHex string) error {
deposit, err := rollups.DecodeErc20Deposit(payloadHex)
if err != nil {
return fmt.Errorf("HandleErc20: error decoding deposit: %s", err)
}
infolog.Println("Received",new(big.Float).Quo(new(big.Float).SetInt(deposit.Amount),big.NewFloat(1e18)),"tokens",deposit.TokenAddress,"Erc20 deposit from",deposit.Depositor,"data:",string(deposit.Data))
}
infolog.Println("Received",deposit.Amount,"tokens",deposit.TokenAddress,"Erc20 deposit from",deposit.Depositor,"data:",string(deposit.Data))

voucher := rollups.Erc20TransferVoucher(deposit.Depositor, deposit.TokenAddress, deposit.Amount)
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
Expand All @@ -62,17 +56,13 @@ func HandleErc721(metadata *rollups.Metadata, payloadHex string) error {

infolog.Println("Received id",deposit.TokenId,deposit.TokenAddress,"Erc721 deposit from",deposit.Depositor,"data:",string(deposit.Data))

if dappAddress != "" {
voucher := rollups.Erc721SafeTransferVoucher(dappAddress, deposit.Depositor, deposit.TokenAddress, deposit.TokenId)
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
} else {
infolog.Println("Can't generate voucher as there is no dapp address configured")
voucher := rollups.Erc721SafeTransferVoucher(metadata.AppContract, deposit.Depositor, deposit.TokenAddress, deposit.TokenId)
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
return nil
}

Expand All @@ -84,17 +74,13 @@ func HandleErc1155Single(metadata *rollups.Metadata, payloadHex string) error {

infolog.Println("Received ",deposit.Amount,"tokens of id",deposit.TokenId,deposit.TokenAddress,"Erc1155 Single deposit from",deposit.Depositor,"base layer data:",string(deposit.BaseLayerData),"and exec layer data:",string(deposit.ExecLayerData))

if dappAddress != "" {
voucher := rollups.Erc1155SafeTransferFromVoucher(dappAddress, deposit.Depositor, deposit.TokenAddress, deposit.TokenId, deposit.Amount, make([]byte,0))
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
} else {
infolog.Println("Can't generate voucher as there is no dapp address configured")
voucher := rollups.Erc1155SafeTransferFromVoucher(metadata.AppContract, deposit.Depositor, deposit.TokenAddress, deposit.TokenId, deposit.Amount, make([]byte,0))
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
return nil
}

Expand All @@ -106,36 +92,19 @@ func HandleErc1155Batch(metadata *rollups.Metadata, payloadHex string) error {

infolog.Println("Received ",deposit.Amounts,"amounts of ids",deposit.TokenIds,deposit.TokenAddress,"Erc1155 Batch deposit from",deposit.Depositor,"base layer data:",string(deposit.BaseLayerData),"and exec layer data:",string(deposit.ExecLayerData))

if dappAddress != "" {
voucher := rollups.Erc1155SafeBatchTransferFromVoucher(dappAddress, deposit.Depositor, deposit.TokenAddress, deposit.TokenIds, deposit.Amounts, make([]byte,0))
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}
infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
} else {
infolog.Println("Can't generate voucher as there is no dapp address configured")
}
return nil
}

func HandleRelay(metadata *rollups.Metadata, payloadHex string) error {
infolog.Println("Dapp Relay, sender is",metadata.MsgSender,"and the my address is", payloadHex)
dappAddress = payloadHex
report := rollups.Report{Payload: rollups.Str2Hex("Set address relay")}
_, err := rollups.SendReport(&report)
voucher := rollups.Erc1155SafeBatchTransferFromVoucher(metadata.AppContract, deposit.Depositor, deposit.TokenAddress, deposit.TokenIds, deposit.Amounts, make([]byte,0))
infolog.Println("Sending voucher destination",voucher.Destination,"payload",voucher.Payload)
res, err := rollups.SendVoucher(&voucher)
if err != nil {
return fmt.Errorf("HandleFixed: error making http request: %s", err)
return fmt.Errorf("HandleErc721: error making http request: %s", err)
}

infolog.Println("Received voucher status", strconv.Itoa(res.StatusCode))
return nil
}

func main() {
handler.InitializeRollupsAddresses("localhost")

handler.HandleFixedAddress(handler.RollupsAddresses.DappAddressRelay, HandleRelay)

handler.HandleFixedAddress(handler.RollupsAddresses.EtherPortalAddress, HandleEther)
handler.HandleFixedAddress(handler.RollupsAddresses.Erc20PortalAddress, HandleErc20)
handler.HandleFixedAddress(handler.RollupsAddresses.Erc721PortalAddress, HandleErc721)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func HandleSet(metadata *rollups.Metadata, payloadMap map[string]interface{}) er
return fmt.Errorf("HandleSet: error making http request: %s", err)
}

noticePayload,err := noticeCodec.Encode([]interface{}{metadata.Timestamp,key,value})
noticePayload,err := noticeCodec.Encode([]interface{}{metadata.BlockTimestamp,key,value})
if err != nil {
return fmt.Errorf("HandleSet: encoding notice: %s", err)
}
Expand All @@ -96,10 +96,10 @@ func main() {

noticeCodec = abihandler.NewCodec([]string{"uint","string","string"})

setCodec := abihandler.NewHeaderCodec("dapp","set",[]string{"string key","string value"})
setCodec := abihandler.NewHeaderCodec("dapp.set",[]string{"string key","string value"})
handler.HandleAdvanceRoute(setCodec, HandleSet)

getCodec := abihandler.NewHeaderCodec("dapp","get",[]string{"string"})
getCodec := abihandler.NewHeaderCodec("dapp.get",[]string{"string"})
handler.HandleAdvanceRoute(getCodec, HandleAdvanceGet)
handler.HandleInspectRoute(getCodec, HandleGet)

Expand Down
Loading