Skip to content

Commit

Permalink
Merge pull request #11 from xssnick/addr-improvements
Browse files Browse the repository at this point in the history
LoadAddr check type
  • Loading branch information
xssnick authored May 7, 2022
2 parents 454910e + 4e69841 commit d736bdd
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 31 deletions.
11 changes: 6 additions & 5 deletions address/addr.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ type AddressFlags struct {
testnet bool
}

func NewAddressFromBytes(bytes []byte) *Address {
func NewAddress(flags byte, workchain byte, data []byte) *Address {
// TODO: all types of addrs
// TODO: flags parse
return &Address{
flags: ParseFlags(bytes[0]),
workchain: bytes[1],
data: bytes[2:],
flags: ParseFlags(flags),
workchain: workchain,
data: data,
}
}

Expand Down Expand Up @@ -75,9 +75,10 @@ func ParseAddr(addr string) (*Address, error) {
return nil, errors.New("invalid address")
}

a := NewAddressFromBytes(data[:len(data)-2])
a := NewAddress(data[0], data[1], data[2:len(data)-2])
return a, nil
}

func (a *Address) Checksum() uint16 {
return crc16.Checksum(a.prepareChecksumData(), crc16.MakeTable(crc16.CRC16_XMODEM))
}
Expand Down
Binary file not shown.
55 changes: 55 additions & 0 deletions example/nft-info/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import (
"context"
"fmt"
"github.com/xssnick/tonutils-go/address"
"github.com/xssnick/tonutils-go/liteclient"
"github.com/xssnick/tonutils-go/ton"
"github.com/xssnick/tonutils-go/tvm/cell"
"log"
)

func main() {
client := liteclient.NewClient()

// connect to mainnet lite server
err := client.Connect(context.Background(), "135.181.140.212:13206", "K0t3+IWLOXHYMvMcrGZDPs+pn58a17LFbnXoQkKc2xw=")
if err != nil {
log.Fatalln("connection err: ", err.Error())
return
}

// initialize ton api lite connection wrapper
api := ton.NewAPIClient(client)

// we need fresh block info to run get methods
b, err := api.GetBlockInfo(context.Background())
if err != nil {
log.Fatalln("get block err:", err.Error())
return
}

// call method to get data from nft address
res, err := api.RunGetMethod(context.Background(), b, address.MustParseAddr("EQAMo8TmviyZpBLLJMDDwYDhFsdyj26XoAM4_mNyMtfxuT6O"), "get_nft_data")
if err != nil {
log.Fatalln("run get method err:", err.Error())
return
}

collectionAddr, err := res[2].(*cell.Cell).BeginParse().LoadAddr()
if err != nil {
log.Fatalln("addr err:", err.Error())
return
}

ownerAddr, err := res[3].(*cell.Cell).BeginParse().LoadAddr()
if err != nil {
log.Fatalln("addr err:", err.Error())
return
}

fmt.Println("NFT collection: ", collectionAddr.String())
fmt.Println("NFT owner: ", ownerAddr.String())
fmt.Println("Content:", res[4].(*cell.Cell).Dump())
}
7 changes: 6 additions & 1 deletion ton/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,15 @@ func (c *APIClient) RunGetMethod(ctx context.Context, blockInfo *tlb.BlockInfo,
if err != nil {
return nil, err
}

// TODO: load ref ids

ref, err := loader.LoadRef()
if err != nil {
return nil, err
}
//Seek to begin

// seek to begin
_, err = ref.LoadSlice(int(begin))
if err != nil {
return nil, err
Expand All @@ -262,6 +266,7 @@ func (c *APIClient) RunGetMethod(ctx context.Context, blockInfo *tlb.BlockInfo,
if err != nil {
return nil, err
}

// represent slice as cell, to parse it easier
result = append(result, cell.BeginCell().MustStoreSlice(payload, sz).EndCell())
default:
Expand Down
4 changes: 2 additions & 2 deletions tvm/cell/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func TestCell25(t *testing.T) {
func TestCellReadSmall(t *testing.T) {
c := BeginCell()

bs := []byte{0xFF, 0x00, 0x00}
bs := []byte{0b10101010, 0x00, 0x00}

err := c.StoreSlice(bs, 24)
if err != nil {
Expand All @@ -172,7 +172,7 @@ func TestCellReadSmall(t *testing.T) {
return
}

if res != 1 {
if (res != 1 && i%2 == 0) || (res != 0 && i%2 == 1) {
t.Fatal("not eq " + fmt.Sprint(i*2))
return
}
Expand Down
30 changes: 7 additions & 23 deletions tvm/cell/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cell

import (
"encoding/hex"
"github.com/xssnick/tonutils-go/address"
"strings"
)

Expand Down Expand Up @@ -31,33 +30,18 @@ func (c *Cell) BeginParse() *LoadCell {
}
}

func (c *Cell) ParseAddr() (*address.Address, error) {
loader := c.BeginParse()

//TODO ??? skipping 3 bits as in tonweb - why?
_, err := loader.LoadUInt(3)
if err != nil {
return nil, err
}

data, err := loader.LoadSlice(264)
if err != nil {
return nil, err
}

a := address.NewAddressFromBytes(data)
return a, nil
}

func (c *Cell) Dump() string {
return c.dump(0)
}

func (c *Cell) dump(deep int) string {
str := "\n" + strings.Repeat(" ", deep) + "[" + hex.EncodeToString(c.data) + "]" + " -> {"
for _, ref := range c.refs {
str += ref.dump(deep+1) + ", "
str := strings.Repeat(" ", deep) + "[" + hex.EncodeToString(c.data) + "]" + " -> {"
if len(c.refs) > 0 {
for _, ref := range c.refs {
str += "\n" + ref.dump(deep+1) + ", " + "\n"
}
str += strings.Repeat(" ", deep)
}

return str + "\n" + strings.Repeat(" ", deep) + "}"
return str + "}"
}
38 changes: 38 additions & 0 deletions tvm/cell/load.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cell

import (
"errors"
"github.com/xssnick/tonutils-go/address"
"math/big"
)

Expand Down Expand Up @@ -117,6 +119,9 @@ func (c *LoadCell) LoadSlice(sz int) ([]byte, error) {
}
} else {
b = c.data[i]
if unusedBits > 0 {
b <<= byte(8 - unusedBits)
}
}

if leftSz == 0 {
Expand Down Expand Up @@ -145,6 +150,39 @@ func (c *LoadCell) LoadSlice(sz int) ([]byte, error) {
return loadedData, nil
}

func (c *LoadCell) LoadAddr() (*address.Address, error) {
typ, err := c.LoadUInt(2)
if err != nil {
return nil, err
}

// TODO: support of all types of addresses, currently only std supported, skipping 3 bits
if typ != 2 {
return nil, errors.New("not supported type of address, currently only std supported")
}

isAnycast, err := c.LoadUInt(1)
if err != nil {
return nil, err
}

if isAnycast == 1 {
return nil, errors.New("currently anycast addr is not supported")
}

workchain, err := c.LoadSlice(8)
if err != nil {
return nil, err
}

data, err := c.LoadSlice(256)
if err != nil {
return nil, err
}

return address.NewAddress(0, workchain[0], data), nil
}

func (c *LoadCell) RestBits() (int, []byte, error) {
left := c.bitsSz - c.loadedSz
data, err := c.LoadSlice(left)
Expand Down

0 comments on commit d736bdd

Please sign in to comment.