CONCAT_ARRAYS(Byte array from "TX" (protocol.Transaction), Parent Tx id byte array, index of inner-txn in big endian byte array, inner-txn msgpack encoded body byte array)
Sequence of Byte Arrays in Txid Byte array from "TX" (protocol.Transaction): The function starts by getting a buffer from getTxEncodingBuf(), which already contains the protocol.Transaction bytes.this is the first part of the sequence.
Parent Tx id byte array: The function then appends the parent transaction ID (parent[:]) to the buffer. This becomes the second part of the sequence.
Index of inner-txn in big endian byte array: An 8-byte array (indexBuf) is created to store the index in big-endian format. This is then appended to the existing buffer, making it the third part of the sequence.
Inner-txn msgpack encoded body byte array: Finally, the transaction (tx) itself is msgpack encoded using tx.MarshalMsg(input) and appended to the buffer. This is the fourth and final part of the sequence.
according to the code the exact order is:
- Byte array from "TX" (protocol.Transaction)
- Parent Tx id byte array
- Index of inner-txn in big endian byte array
- Inner-txn msgpack encoded body byte array
// txEncodingPool holds temporary byte slice buffers used for encoding transaction messages.
// Note, it prepends protocol.Transaction tag to the buffer economizing on subsequent append ops.
var txEncodingPool = sync.Pool{
New: func() interface{} {
size := txAllocSize() + len(protocol.Transaction)
buf := make([]byte, len(protocol.Transaction), size)
copy(buf, []byte(protocol.Transaction))
return &txEncodingBuf{b: buf}
},
}
// getTxEncodingBuf returns a wrapped byte slice that can be used for encoding a
// temporary message. The byte slice length of encoded Transaction{} object.
// The caller gets full ownership of the byte slice,
// but is encouraged to return it using putEncodingBuf().
func getTxEncodingBuf() *txEncodingBuf {
buf := txEncodingPool.Get().(*txEncodingBuf)
return buf
}
type MicroAlgos struct {
Raw uint64
}
func (a MicroAlgos) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, msgp.Uint64Size)
o = msgp.AppendUint64(o, a.Raw)
return
}
// putTxEncodingBuf places a byte slice into the pool of temporary buffers
// for encoding. The caller gives up ownership of the byte slice when
// passing it to putTxEncodingBuf().
func putTxEncodingBuf(buf *txEncodingBuf) {
buf.b = buf.b[:len(protocol.Transaction)]
txEncodingPool.Put(buf)
}
// The main function in subject
func (tx Transaction) InnerID(parent Txid, index int) Txid {
// inner-txn body bytes
buf := getTxEncodingBuf()
// append parent TXN ID
input := append(buf.b, parent[:]...)
var indexBuf [8]byte
binary.BigEndian.PutUint64(indexBuf[:], uint64(index))
// Append index
input = append(input, indexBuf[:]...)
enc := tx.MarshalMsg(input)
if cap(enc) > cap(buf.b) {
buf.b = enc
}
defer putTxEncodingBuf(buf)
return Txid(crypto.Hash(enc))
}

const ALGORAND_TRANSACTION_LENGTH = 52;
tag = Buffer.from('TX');
rawTxID() {
const enMsg = this.toByte();
const gh = Buffer.from(utils.concatArrays(this.tag, enMsg));
return Buffer.from(nacl.genericHash(gh));
}
txID() {
const hash = this.rawTxID();
return base32.encode(hash).slice(0, ALGORAND_TRANSACTION_LENGTH);
}
export function genericHash(arr: sha512.Message) {
return sha512.sha512_256.array(arr);
}
toByte() {
return encoding.encode(this.get_obj_for_encoding());
}
go-algorand exact funciton for generating inner TXN ID
- testRegenerateTransaction : Main method containing majority of the code for easier tracking and debug
- printTransactionLogsFromBlocks
- printTransactionLogsFromBlocks (gets the txn, inner TXN and logs from /block endpoint of Algod)
- printTransactionLogsFromIndexer (gets and prints logs from indexer , just for logging and not used in process)
How to run:
- branch the gora-desense-smartcontracts repo
- pull your created branch
- npm install
- npm start
Please use LTS version of nodeJS