I'm trying to parse the data from the ADNL lib by tonutils-go and deliver the data by GRPC.
The data I need is structured as
// struct from tonutils-go
type Transaction struct {
_ Magic `tlb:"$0111"`
AccountAddr []byte `tlb:"bits 256"`
LT uint64 `tlb:"## 64"`
PrevTxHash []byte `tlb:"bits 256"`
PrevTxLT uint64 `tlb:"## 64"`
Now uint32 `tlb:"## 32"`
OutMsgCount uint16 `tlb:"## 15"`
OrigStatus AccountStatus `tlb:"."`
EndStatus AccountStatus `tlb:"."`
IO struct {
In *Message `tlb:"maybe ^"`
Out *MessagesList `tlb:"maybe ^"`
} `tlb:"^"`
TotalFees CurrencyCollection `tlb:"."`
StateUpdate HashUpdate `tlb:"^"` // of Account
Description TransactionDescription `tlb:"^"`
// not in scheme, but will be filled based on request data for flexibility
Hash []byte `tlb:"-"`
}
type TransactionDescription struct {
Description any `tlb:"."`
}
type TransactionDescriptionOrdinary struct {
_ Magic `tlb:"$0000"`
CreditFirst bool `tlb:"bool"`
StoragePhase *StoragePhase `tlb:"maybe ."`
CreditPhase *CreditPhase `tlb:"maybe ."`
ComputePhase ComputePhase `tlb:"."`
ActionPhase *ActionPhase `tlb:"maybe ^"`
Aborted bool `tlb:"bool"`
BouncePhase *BouncePhase `tlb:"maybe ."`
Destroyed bool `tlb:"bool"`
}
type ComputePhase struct {
Phase any `tlb:"."`
}
type ComputePhaseVM struct {
_ Magic `tlb:"$1"`
Success bool `tlb:"bool"`
MsgStateUsed bool `tlb:"bool"`
AccountActivated bool `tlb:"bool"`
GasFees Coins `tlb:"."`
Details struct {
GasUsed *big.Int `tlb:"var uint 7"`
GasLimit *big.Int `tlb:"var uint 7"`
GasCredit *big.Int `tlb:"maybe var uint 3"`
Mode int8 `tlb:"## 8"`
ExitCode int32 `tlb:"## 32"`
ExitArg *int32 `tlb:"maybe ## 32"`
VMSteps uint32 `tlb:"## 32"`
VMInitStateHash []byte `tlb:"bits 256"`
VMFinalStateHash []byte `tlb:"bits 256"`
} `tlb:"^"`
}
The protobuf of TxTest:
message TxTest {
int32 exitCode = 1;
}
The data I want to parse is ExitCode and the code as following:
list, err := api.ListTransactions(context.Background(), addr, 1, uint64(txInfo.TxLT), data)
if err != nil {
log.Printf("send err: %s", err.Error())
return nil, err
}
for _, t := range list {
a := t.Description.Description
var result tlb.TransactionDescriptionOrdinary
b, err := json.MarshalIndent(a, "", " ")
if err != nil {
fmt.Println("error:", err)
}
json.Unmarshal([]byte(string(b)), &result)
var computePhase tlb.ComputePhaseVM
c, err := json.MarshalIndent(result.ComputePhase.Phase, "", " ")
if err != nil {
fmt.Println("error:", err)
}
json.Unmarshal([]byte(string(c)), &computePhase)
detail := &pb.TxTest{
ExitCode: computePhase.Details.ExitCode,
}
detail2 := struct {
ExitCode int32 `json:"exit_code"`
}{
ExitCode: computePhase.Details.ExitCode,
}
fmt.Printf("detail: %+v\n", detail)
fmt.Printf("detail2: %+v\n", detail2)
}
The data struct of one transaction is:
{
"AccountAddr": "HYmM1/kK6GB2DLV3zVkIRyEpKoHRTF/jG8K7tTG91sQ=",
"LT": 11898016000001,
"PrevTxHash": "iKGjsxdT0gzIJXGNIlvxy0+a1gGEQDED4f7ZAJ9dlmc=",
"PrevTxLT": 11897712000001,
"Now": 1685602760,
"OutMsgCount": 1,
"OrigStatus": "ACTIVE",
"EndStatus": "ACTIVE",
"IO": {
"In": {
"MsgType": "EXTERNAL_IN",
"Msg": {
"SrcAddr": "NONE",
"DstAddr": "EQAdiYzX-QroYHYMtXfNWQhHISkqgdFMX-Mbwru1Mb3WxN5D",
"ImportFee": "0",
"StateInit": null,
"Body": {}
}
},
"Out": {
"List": {}
}
},
"TotalFees": {
"Coins": "22324812",
"ExtraCurrencies": {}
},
"StateUpdate": {
"OldHash": "WUkeXyOS8hsWyQYRLHPmJHpfMUSID8oDTAq6fY20pyQ=",
"NewHash": "e8tn4cP4lAkFwvDcGc/VqBZ7lZeB4mhjMbRFE8rpsQA="
},
"Description": {
"Description": {
"CreditFirst": true,
"StoragePhase": {
"StorageFeesCollected": "484",
"StorageFeesDue": null,
"StatusChange": {
"Type": "UNCHANGED"
}
},
"CreditPhase": null,
"ComputePhase": {
"Phase": {
"Success": true,
"MsgStateUsed": false,
"AccountActivated": false,
"GasFees": "19862000",
"Details": {
"GasUsed": 19862,
"GasLimit": 0,
"GasCredit": 10000,
"Mode": 0,
"ExitCode": 0,
"ExitArg": null,
"VMSteps": 404,
"VMInitStateHash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"VMFinalStateHash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
}
}
},
"ActionPhase": {
"Success": true,
"Valid": true,
"NoFunds": false,
"StatusChange": {
"Type": "UNCHANGED"
},
"TotalFwdFees": "1000000",
"TotalActionFees": "333328",
"ResultCode": 0,
"ResultArg": null,
"TotalActions": 1,
"SpecActions": 0,
"SkippedActions": 0,
"MessagesCreated": 1,
"ActionListHash": "Fkoo2xX9jU4YxTGJlrUjvaYrRWTrYHEBkUywUYg9AV4=",
"TotalMsgSize": {
"Cells": 1,
"Bits": 697
}
},
"Aborted": false,
"BouncePhase": null,
"Destroyed": false
}
},
"Hash": "VMXfRKfIEtmAiHm3brTvhSkAidE1CkgRW8RQBVarJtQ="
}
and output of detail
and detail2
are:
detail:
detail2: {ExitCode:0}
My question is why the struct generated by protoc
couldn't parse the exitCode
from the transaction
but the struct I defined could work well?
How can I inject the data into the struct TxTest
which is generated by protoc
, and let me transmit the data by GRPC
?