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
151 changes: 151 additions & 0 deletions abi-tolk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Tolk ABI for Golang

This package generates types and code for interacting with smart contracts given their Tolk-based ABI.

It generates:

- Types for contract storage and messages, including:
- marshaling/unmarshalling from/to cell
- typed init state builders
- Get method wrappers for each contract method

## Directory layout

```
abi-tolk/
schemas/
cocoon/ # example: Cocoon contracts
{group}/ # other contracts, can be a group of related contracts
{contract1}.tolk # Tolk source code
{contract1}.json # the ABI JSON generated by Tolk for {contract1}.tolk
abiGenerated/
cocoon/ # package abiCocoon
{name}/ # package abi{Name}
{group}/ # package abi{Group}
{contract1}.go # generated code for {contract1}: structs, type aliases,
# get methods, client implementation
{contract1}_marshal.go # marshal to cell/unmarshal from cell
# also get method return types have "unmarshal from stack" functions
executor.go # interfaces for interacting with contracts (+dependency interfaces)

tolk_consts_generated.go # generated code for contract interface constants
shared.go # shared type declarations (types used across multiple contracts in the same group)
shared_marshal.go # marshal to cell/unmarshal from cell

```

## What is supported

### Types

Primitives:

| Tolk type | Go type |
|-----------------|-----------------------------|
| `uintN`, `intN` | `tlb.Uint{N}`, `tlb.Int{N}` |
| `int` | `tlb.Int257` |
| `coins` | `tlb.Coins` |
| `bool` | `bool` |
| `address` | `tlb.InternalAddress` |
| `any_address` | `tlb.MsgAddress` |
| `bitsN` | `tlb.Bits{N}` |
| `cell` | `boc.Cell` |
| `string` | `string` |

Structural:

| Tolk type | Go type |
|------------|---------------|
| `struct X` | `struct X` |
| `array<T>` | `[]T` |
| `Cell<T>` | `tlb.RefT<T>` |

Not supported yet:

* `tuple<T1,Tn>`
* not specialized types:
* `coordinate: Point<int8>` is ok
* but saying contract has storage `Storage<T>` with unknown T is not ok

### Internal and external messages

To be described

### Contract storage

Type representing contract state can be defined in the Tolk ABI:

```tolk
contract cocoon_root {
storage: RootStorage
}

struct RootStorage {
ownerAddress: address
data: Cell<RootData>
params: Cell<CocoonParams>
version: uint32
}
```

All internal and external message builders will receive a `*StateInitT[*RootStorage]` argument:

```go
func (msg RegisterProxy) ToInternal(
dest tlb.InternalAddress,
amount tlb.Grams,
bounce bool,
init *tlb.StateInitT[*RootStorage],
) (tlb.Message, error)
```

Or you can use `tlb.StateInitT` directly to calculate address based
on [the init state](https://docs.ton.org/foundations/messages/deploy).

### Custom cell format

Some cell layout can't be represented as Tolk type. This is a common situation for contracts written in another TVM
language, e.g. FunC.
In this case, Tolk itself let authors to write extension methods
for [custom cell layout](https://docs.ton.org/tolk/features/auto-serialization#custom-serializers-for-custom-types):

```tolk
type MyString = slice

fun MyString.packToBuilder(self, mutate b: builder) {
// custom cell-composition logic
}

fun MyString.unpackFromSlice(mutate s: slice) {
// custom cell-parsing logic
}
```

This is expressed in ABI JSON by a flag, and MarshalTLB/UnmarshalTLB functions are skipped by code generator.
It is advised to put custom logic in `custom_marshal.go` or something like that. If you don't implement custom logic,
you will get a compilation error:

```shell
$ go build ./...
# github.com/tonkeeper/tongo/abi-tolk/abiGenerated/cocoon
abi-tolk/abiGenerated/cocoon/cocoon_wallet_marshal.go:109:21: v.Forward.UnmarshalTLB undefined (type ForwardMsgs has no field or method UnmarshalTLB)
```

Adding custom logic is as simple as implementing `UnmarshalTLB` in a file not generated by Tolk (`custom_marshal.go`
e.g.):

```go
func (m *ForwardMsgs) UnmarshalTLB(c *boc.Cell, decoder *tlb.Decoder) error {
/*
FunC code:
while (cs.slice_refs()) {
var mode = cs~load_uint(8);
send_raw_message(cs~load_ref(), mode);
}
*/
for c.RefsAvailableForRead() > 0 {
// etc.
}
return nil
}
```
211 changes: 211 additions & 0 deletions abi-tolk/abiGenerated/cocoon/cocoon_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading