From b4540a0363441b1f45acbb69598e47170415908b Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Wed, 15 Jun 2022 20:08:07 -0300 Subject: [PATCH 01/49] [contract] composable transactions --- chain/chainhandle.go | 18 +++- contract/contract.go | 24 +++-- contract/vm.go | 57 ++++++++-- contract/vm_multicall.go | 216 ++++++++++++++++++++++++++++++++++++++ contract/vm_multicall.lua | 196 ++++++++++++++++++++++++++++++++++ state/contract.go | 13 +++ types/blockchain.pb.go | 3 + types/transaction.go | 7 +- 8 files changed, 511 insertions(+), 23 deletions(-) create mode 100644 contract/vm_multicall.go create mode 100644 contract/vm_multicall.lua diff --git a/chain/chainhandle.go b/chain/chainhandle.go index 3c8620f67..47010d0ee 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -919,12 +919,21 @@ func executeTx( return err } - if recipient, err = name.Resolve(bs, txBody.Recipient, isQuirkTx); err != nil { - return err + isMultiCall := (txBody.Type == types.TxType_MULTICALL) + + if isMultiCall { + recipient = account + } else { + if recipient, err = name.Resolve(bs, txBody.Recipient, isQuirkTx); err != nil { + return err + } } + var receiver *state.V status := "SUCCESS" - if len(recipient) > 0 { + if isMultiCall { + receiver = sender + } else if len(recipient) > 0 { receiver, err = bs.GetAccountStateV(recipient) if receiver != nil && txBody.Type == types.TxType_REDEPLOY { status = "RECREATED" @@ -941,8 +950,9 @@ func executeTx( var txFee *big.Int var rv string var events []*types.Event + switch txBody.Type { - case types.TxType_NORMAL, types.TxType_REDEPLOY, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_DEPLOY: + case types.TxType_NORMAL, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_MULTICALL, types.TxType_DEPLOY, types.TxType_REDEPLOY: rv, events, txFee, err = contract.Execute(bs, cdb, tx.GetTx(), sender, receiver, bi, preLoadService, false) sender.SubBalance(txFee) case types.TxType_GOVERNANCE: diff --git a/contract/contract.go b/contract/contract.go index 1be92f8d5..18a46836e 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -71,6 +71,7 @@ func Execute( isFeeDelegation bool, ) (rv string, events []*types.Event, usedFee *big.Int, err error) { txBody := tx.GetBody() + isMultiCall := (txBody.Type == types.TxType_MULTICALL) usedFee = txFee(len(txBody.GetPayload()), bs.GasPrice, bi.Version) @@ -84,7 +85,7 @@ func Execute( receiver.AddBalance(txBody.GetAmountBigInt()) } - if !receiver.IsDeploy() && len(receiver.State().CodeHash) == 0 { + if !isMultiCall && !receiver.IsDeploy() && len(receiver.State().CodeHash) == 0 { // Before the chain version 3, any tx with no code hash is // unconditionally executed as a simple Aergo transfer. Since this // causes confusion, emit error for call-type tx with a wrong address @@ -127,10 +128,16 @@ func Execute( } } - contractState, err := bs.OpenContractState(receiver.AccountID(), receiver.State()) + var contractState *state.ContractState + if isMultiCall { + contractState = bs.GetMultiCallState(sender.AccountID(), sender.State()) + } else { + contractState, err = bs.OpenContractState(receiver.AccountID(), receiver.State()) + } if err != nil { return } + if receiver.IsRedeploy() { if err = checkRedeploy(sender, receiver, contractState); err != nil { return @@ -163,7 +170,7 @@ func Execute( } else { ctx := newVmContext(bs, cdb, sender, receiver, contractState, sender.ID(), tx.GetHash(), bi, "", true, false, receiver.RP(), - preLoadService, txBody.GetAmountBigInt(), gasLimit, isFeeDelegation) + preLoadService, txBody.GetAmountBigInt(), gasLimit, isFeeDelegation, isMultiCall) if receiver.IsDeploy() { rv, events, ctrFee, err = Create(contractState, txBody.Payload, receiver.ID(), ctx) @@ -196,9 +203,11 @@ func Execute( } } - err = bs.StageContractState(contractState) - if err != nil { - return "", events, usedFee, err + if !isMultiCall { + err = bs.StageContractState(contractState) + if err != nil { + return "", events, usedFee, err + } } return rv, events, usedFee, nil @@ -269,7 +278,8 @@ func preLoadWorker() { ctx := newVmContext(bs, nil, nil, receiver, contractState, txBody.GetAccount(), tx.GetHash(), reqInfo.bi, "", false, false, receiver.RP(), reqInfo.preLoadService, txBody.GetAmountBigInt(), txBody.GetGasLimit(), - txBody.Type == types.TxType_FEEDELEGATION) + txBody.Type == types.TxType_FEEDELEGATION, + txBody.Type == types.TxType_MULTICALL) ex, err := PreloadEx(bs, contractState, txBody.Payload, receiver.ID(), ctx) if ex == nil && ctx.traceFile != nil { diff --git a/contract/vm.go b/contract/vm.go index eb0f2ca53..50d90747f 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -93,6 +93,7 @@ type vmContext struct { isQuery bool nestedView int32 isFeeDelegation bool + isMultiCall bool service C.int callState map[types.AccountID]*callState lastRecoveryEntry *recoveryEntry @@ -169,14 +170,14 @@ func getTraceFile(blkno uint64, tx []byte) *os.File { return f } -func newVmContext(blockState *state.BlockState, cdb ChainAccessor, sender, reciever *state.V, +func newVmContext(blockState *state.BlockState, cdb ChainAccessor, sender, receiver *state.V, contractState *state.ContractState, senderID []byte, txHash []byte, bi *types.BlockHeaderInfo, node string, confirmed bool, - query bool, rp uint64, service int, amount *big.Int, gasLimit uint64, feeDelegation bool) *vmContext { + query bool, rp uint64, service int, amount *big.Int, gasLimit uint64, feeDelegation bool, isMultiCall bool) *vmContext { - cs := &callState{ctrState: contractState, curState: reciever.State()} + cs := &callState{ctrState: contractState, curState: receiver.State()} ctx := &vmContext{ - curContract: newContractInfo(cs, senderID, reciever.ID(), rp, amount), + curContract: newContractInfo(cs, senderID, receiver.ID(), rp, amount), bs: blockState, cdb: cdb, origin: senderID, @@ -189,10 +190,11 @@ func newVmContext(blockState *state.BlockState, cdb ChainAccessor, sender, recie gasLimit: gasLimit, remainedGas: gasLimit, isFeeDelegation: feeDelegation, + isMultiCall: isMultiCall, } ctx.callState = make(map[types.AccountID]*callState) - ctx.callState[reciever.AccountID()] = cs - if sender != nil { + ctx.callState[receiver.AccountID()] = cs + if sender != nil && sender != receiver { ctx.callState[sender.AccountID()] = &callState{curState: sender.State()} } if TraceBlockNo != 0 && TraceBlockNo == ctx.blockInfo.No { @@ -759,6 +761,13 @@ func refreshGas(ctx *vmContext, L *LState) { } } +func getMultiCallInfo(ci *types.CallInfo, payload []byte) error { + payload = append([]byte{'['}, payload...) + payload = append(payload, ']') + ci.Name = "execute" + return getCallInfo(&ci.Args, payload, []byte("multicall")) +} + func getCallInfo(ci interface{}, args []byte, contractAddress []byte) error { d := json.NewDecoder(bytes.NewReader(args)) d.UseNumber() @@ -775,16 +784,26 @@ func getCallInfo(ci interface{}, args []byte, contractAddress []byte) error { func Call( contractState *state.ContractState, - code, contractAddress []byte, + payload, contractAddress []byte, ctx *vmContext, ) (string, []*types.Event, *big.Int, error) { var err error var ci types.CallInfo - contract := getContract(contractState, ctx.bs) + var contract []byte + + if ctx.isMultiCall { + contract = getMultiCallContract(contractState) + } else { + contract = getContract(contractState, ctx.bs) + } if contract != nil { - if len(code) > 0 { - err = getCallInfo(&ci, code, contractAddress) + if ctx.isMultiCall { + err = getMultiCallInfo(&ci, payload) + } else { + if len(payload) > 0 { + err = getCallInfo(&ci, payload, contractAddress) + } } } else { addr := types.EncodeAddress(contractAddress) @@ -795,7 +814,7 @@ func Call( return "", nil, ctx.usedFee(), err } if ctrLgr.IsDebugEnabled() { - ctrLgr.Debug().Str("abi", string(code)).Str("contract", types.EncodeAddress(contractAddress)).Msg("call") + ctrLgr.Debug().Str("abi", string(payload)).Str("contract", types.EncodeAddress(contractAddress)).Msg("call") } contexts[ctx.service] = ctx @@ -825,11 +844,13 @@ func Call( } return "", ce.getEvents(), ctx.usedFee(), err } + err = ce.commitCalledContract() if err != nil { ctrLgr.Error().Err(err).Str("contract", types.EncodeAddress(contractAddress)).Msg("commit state") return "", ce.getEvents(), ctx.usedFee(), err } + if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[ret] : %s\n", ce.jsonRet)) _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[usedFee] : %s\n", ctx.usedFee().String())) @@ -845,6 +866,7 @@ func Call( _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[CALL END] : %s(%s)\n", types.EncodeAddress(contractAddress), types.ToAccountID(contractAddress))) } + return ce.jsonRet, ce.getEvents(), ctx.usedFee(), nil } @@ -1227,6 +1249,9 @@ func getCode(contractState *state.ContractState, bs *state.BlockState) ([]byte, } func getContract(contractState *state.ContractState, bs *state.BlockState) []byte { + if len(contractState.GetCodeHash()) == 0 { + return nil + } code, err := getCode(contractState, bs) if err != nil { return nil @@ -1234,6 +1259,16 @@ func getContract(contractState *state.ContractState, bs *state.BlockState) []byt return luacUtil.LuaCode(code).ByteCode() } +func getMultiCallContract(contractState *state.ContractState) []byte { + code := luacUtil.LuaCode(multicall_payload) + if !code.IsValidFormat() { + ctrLgr.Warn().Msg("multicall_payload") + return nil + } + contractState.SetMultiCallCode(multicall_payload) + return code.ByteCode() +} + func GetABI(contractState *state.ContractState, bs *state.BlockState) (*types.ABI, error) { var abi *types.ABI diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go new file mode 100644 index 000000000..f353a1df3 --- /dev/null +++ b/contract/vm_multicall.go @@ -0,0 +1,216 @@ +package contract + +var multicall_payload = []byte { + 0xd4,0x0c,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, + 0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00, + 0x00,0x00,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, + 0x37,0x02,0x01,0x04,0x00,0x03,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, + 0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x47,0x03,0x01,0x00, + 0x43,0x01,0x00,0x00,0x0a,0x76,0x61,0x6c,0x75,0x65,0x09,0x63,0x61,0x6c,0x6c,0x0d, + 0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x41,0x02,0x00,0x05,0x00,0x03,0x01,0x08, + 0x34,0x00,0x03,0x00,0x36,0x01,0x00,0x00,0x36,0x03,0x01,0x00,0x39,0x03,0x02,0x03, + 0x47,0x04,0x00,0x00,0x41,0x01,0x01,0x00,0x3f,0x01,0x00,0x00,0x4c,0x00,0x02,0x00, + 0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x0a,0x70, + 0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x53,0x02,0x01,0x07,0x00,0x04, + 0x01,0x0b,0x34,0x01,0x03,0x00,0x36,0x02,0x00,0x00,0x36,0x04,0x01,0x00,0x39,0x04, + 0x02,0x04,0x39,0x04,0x03,0x04,0x12,0x06,0x00,0x00,0x42,0x04,0x02,0x02,0x47,0x05, + 0x01,0x00,0x41,0x02,0x01,0x00,0x3f,0x02,0x00,0x00,0x4c,0x01,0x02,0x00,0x0a,0x76, + 0x61,0x6c,0x75,0x65,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61, + 0x63,0x74,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x28,0x00, + 0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03, + 0x00,0x00,0x44,0x01,0x02,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x0d,0x63, + 0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x29,0x00,0x02,0x06,0x00,0x02,0x00,0x05,0x36, + 0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x12,0x04,0x00,0x00,0x12,0x05,0x01,0x00,0x44, + 0x02,0x03,0x00,0x09,0x73,0x65,0x6e,0x64,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63, + 0x74,0x18,0x00,0x02,0x03,0x00,0x01,0x00,0x03,0x36,0x02,0x00,0x00,0x3c,0x01,0x00, + 0x02,0x4b,0x00,0x01,0x00,0x09,0x76,0x61,0x72,0x73,0x2c,0x00,0x01,0x03,0x00,0x02, + 0x00,0x05,0x36,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x3c,0x02, + 0x00,0x01,0x4b,0x00,0x01,0x00,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75, + 0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x38, + 0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x03,0x03,0x00,0x00,0x00,0x02,0x3c, + 0x02,0x01,0x00,0x4b,0x00,0x01,0x00,0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36, + 0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b, + 0x00,0x01,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65, + 0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00, + 0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x72,0x65,0x6d, + 0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x20,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x21,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x22,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x23,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x25,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, + 0x02,0x24,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x23,0x00,0x01,0x04,0x00,0x02,0x00, + 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, + 0x00,0x09,0x73,0x71,0x72,0x74,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x25,0x02,0x00, + 0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00, + 0x00,0x43,0x00,0x00,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72, + 0x69,0x6e,0x67,0x22,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39, + 0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00, + 0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d, + 0x61,0x74,0x63,0x68,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00, + 0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43, + 0x00,0x00,0x00,0x09,0x67,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25, + 0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12, + 0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62, + 0x69,0x67,0x6e,0x75,0x6d,0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00, + 0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62, + 0x65,0x72,0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03, + 0x00,0x00,0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23, + 0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12, + 0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a, + 0x73,0x6f,0x6e,0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39, + 0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f, + 0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36, + 0x00,0x00,0x00,0x36,0x02,0x01,0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27, + 0x03,0x02,0x00,0x36,0x04,0x03,0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47, + 0x07,0x00,0x00,0x3f,0x07,0x00,0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42, + 0x00,0x03,0x01,0x4b,0x00,0x01,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a, + 0x73,0x6f,0x6e,0x17,0x61,0x73,0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61, + 0x69,0x6c,0x65,0x64,0x3a,0x20,0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65, + 0x72,0x74,0x03,0x80,0x80,0xc0,0x99,0x04,0x80,0x08,0x00,0x01,0x17,0x00,0x19,0x01, + 0xd6,0x01,0x2b,0x01,0x02,0x00,0x2b,0x02,0x01,0x00,0x2c,0x03,0x09,0x00,0x29,0x0a, + 0x01,0x00,0x15,0x0b,0x00,0x00,0x03,0x0a,0x0b,0x00,0x58,0x0b,0xce,0x80,0x55,0x0b, + 0xcd,0x80,0x38,0x0b,0x0a,0x00,0x34,0x0c,0x00,0x00,0x36,0x0d,0x00,0x00,0x12,0x0f, + 0x0b,0x00,0x42,0x0d,0x02,0x04,0x58,0x10,0x01,0x80,0x3c,0x11,0x10,0x0c,0x45,0x10, + 0x03,0x03,0x52,0x10,0xfd,0x7f,0x36,0x0d,0x00,0x00,0x12,0x0f,0x0c,0x00,0x42,0x0d, + 0x02,0x04,0x58,0x10,0x29,0x80,0x29,0x12,0x01,0x00,0x01,0x12,0x10,0x00,0x58,0x12, + 0x26,0x80,0x36,0x12,0x01,0x00,0x12,0x14,0x11,0x00,0x42,0x12,0x02,0x02,0x07,0x12, + 0x02,0x00,0x58,0x12,0x21,0x80,0x15,0x12,0x11,0x00,0x29,0x13,0x03,0x00,0x03,0x13, + 0x12,0x00,0x58,0x12,0x1d,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, + 0x11,0x00,0x29,0x15,0x01,0x00,0x29,0x16,0x01,0x00,0x42,0x12,0x04,0x02,0x07,0x12, + 0x04,0x00,0x58,0x12,0x15,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, + 0x11,0x00,0x29,0x15,0xff,0xff,0x29,0x16,0xff,0xff,0x42,0x12,0x04,0x02,0x07,0x12, + 0x04,0x00,0x58,0x12,0x0d,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, + 0x11,0x00,0x29,0x15,0x02,0x00,0x29,0x16,0xfe,0xff,0x42,0x12,0x04,0x02,0x36,0x13, + 0x05,0x00,0x38,0x13,0x12,0x13,0x0a,0x13,0x00,0x00,0x58,0x13,0x03,0x80,0x36,0x13, + 0x05,0x00,0x38,0x13,0x12,0x13,0x3c,0x13,0x10,0x0c,0x45,0x10,0x03,0x03,0x52,0x10, + 0xd5,0x7f,0x36,0x0d,0x06,0x00,0x39,0x0d,0x07,0x0d,0x12,0x0f,0x0c,0x00,0x29,0x10, + 0x01,0x00,0x42,0x0d,0x03,0x02,0x36,0x0e,0x08,0x00,0x38,0x0e,0x0d,0x0e,0x0f,0x00, + 0x0e,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x0f, + 0x0e,0x00,0x36,0x11,0x09,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f, + 0x00,0x02,0x36,0x10,0x0a,0x00,0x38,0x10,0x0d,0x10,0x0e,0x00,0x10,0x00,0x58,0x10, + 0x7f,0x80,0x36,0x10,0x05,0x00,0x3d,0x0f,0x0b,0x10,0x58,0x0f,0x7c,0x80,0x07,0x0d, + 0x0c,0x00,0x58,0x0f,0x08,0x80,0x36,0x0f,0x0d,0x00,0x36,0x11,0x09,0x00,0x12,0x13, + 0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02, + 0x01,0x00,0x58,0x0f,0x72,0x80,0x07,0x0d,0x0e,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00, + 0x01,0x00,0x58,0x0f,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x6c,0x80,0x0e,0x00, + 0x02,0x00,0x58,0x0f,0x6a,0x80,0x36,0x0f,0x0d,0x00,0x36,0x11,0x09,0x00,0x12,0x13, + 0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02, + 0x01,0x00,0x58,0x0f,0x62,0x80,0x07,0x0d,0x0f,0x00,0x58,0x0f,0x08,0x80,0x0e,0x00, + 0x01,0x00,0x58,0x0f,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x0f,0x5c,0x80,0x2b,0x01, + 0x01,0x00,0x58,0x0f,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x58,0x80,0x07,0x0d, + 0x10,0x00,0x58,0x0f,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x54,0x80,0x07,0x0d, + 0x11,0x00,0x58,0x0f,0x0b,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x09,0x80,0x12,0x03, + 0x0a,0x00,0x27,0x05,0x12,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x06,0x02,0x0c,0x29,0x07, + 0x01,0x00,0x36,0x0f,0x05,0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04,0x0f,0x58,0x0f, + 0x47,0x80,0x07,0x0d,0x13,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f, + 0x0c,0x80,0x12,0x03,0x0a,0x00,0x27,0x05,0x14,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x08, + 0x03,0x0c,0x3a,0x0f,0x04,0x0c,0x0c,0x09,0x0f,0x00,0x58,0x10,0x01,0x80,0x29,0x09, + 0x01,0x00,0x36,0x0f,0x05,0x00,0x3a,0x10,0x02,0x0c,0x3c,0x10,0x04,0x0f,0x58,0x0f, + 0x37,0x80,0x07,0x0d,0x15,0x00,0x58,0x0f,0x25,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f, + 0x23,0x80,0x07,0x05,0x12,0x00,0x58,0x0f,0x09,0x80,0x16,0x07,0x00,0x07,0x15,0x0f, + 0x06,0x00,0x03,0x07,0x0f,0x00,0x58,0x0f,0x2d,0x80,0x36,0x0f,0x05,0x00,0x38,0x10, + 0x07,0x06,0x3c,0x10,0x04,0x0f,0x12,0x0a,0x03,0x00,0x58,0x0f,0x28,0x80,0x07,0x05, + 0x14,0x00,0x58,0x0f,0x26,0x80,0x36,0x0f,0x05,0x00,0x36,0x10,0x05,0x00,0x38,0x10, + 0x04,0x10,0x20,0x10,0x09,0x10,0x3c,0x10,0x04,0x0f,0x29,0x0f,0x00,0x00,0x01,0x0f, + 0x09,0x00,0x58,0x0f,0x04,0x80,0x36,0x0f,0x05,0x00,0x38,0x0f,0x04,0x0f,0x00,0x08, + 0x0f,0x00,0x58,0x0f,0x1a,0x80,0x29,0x0f,0x00,0x00,0x01,0x09,0x0f,0x00,0x58,0x0f, + 0x05,0x80,0x36,0x0f,0x05,0x00,0x38,0x0f,0x04,0x0f,0x01,0x0f,0x08,0x00,0x58,0x0f, + 0x01,0x80,0x58,0x0f,0x12,0x80,0x12,0x0a,0x03,0x00,0x58,0x0f,0x10,0x80,0x07,0x0d, + 0x16,0x00,0x58,0x0f,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x04,0x80,0x36,0x0f, + 0x09,0x00,0x12,0x11,0x0c,0x00,0x44,0x0f,0x02,0x00,0x58,0x0f,0x08,0x80,0x0f,0x00, + 0x01,0x00,0x58,0x0f,0x06,0x80,0x36,0x0f,0x17,0x00,0x2b,0x11,0x01,0x00,0x27,0x12, + 0x18,0x00,0x12,0x13,0x0d,0x00,0x26,0x12,0x13,0x12,0x42,0x0f,0x03,0x01,0x16,0x0a, + 0x00,0x0a,0x58,0x0b,0x2f,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f,0x6d,0x6d,0x61, + 0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x0b,0x61, + 0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09,0x6c,0x6f,0x6f, + 0x70,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x09,0x65,0x61,0x63, + 0x68,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c, + 0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10, + 0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x73,0x6b,0x69,0x70, + 0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72, + 0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72,0x73, + 0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79, + 0x70,0x65,0x0b,0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00, + 0x0f,0x01,0x7b,0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a, + 0x01,0x01,0x00,0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b, + 0x05,0x01,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29, + 0x09,0x01,0x00,0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58, + 0x06,0x07,0x80,0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12, + 0x08,0x02,0x00,0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b, + 0x01,0x00,0x00,0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58, + 0x06,0x3b,0x80,0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58, + 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, + 0x06,0x33,0x80,0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58, + 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, + 0x06,0x2b,0x80,0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58, + 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, + 0x06,0x23,0x80,0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58, + 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, + 0x06,0x1b,0x80,0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58, + 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, + 0x06,0x13,0x80,0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39, + 0x06,0x08,0x06,0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b, + 0x06,0x00,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b, + 0x05,0x02,0x00,0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27, + 0x09,0x0a,0x00,0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f, + 0x00,0x04,0x00,0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29, + 0x07,0x03,0x00,0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36, + 0x06,0x0b,0x00,0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15, + 0x0c,0x00,0x00,0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58, + 0x07,0x05,0x80,0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c, + 0x07,0x02,0x00,0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c, + 0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58, + 0x07,0x06,0x80,0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12, + 0x0b,0x02,0x00,0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07, + 0x6f,0x72,0x08,0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76, + 0x61,0x6c,0x19,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20, + 0x6b,0x6e,0x6f,0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d, + 0x61,0x74,0x63,0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d, + 0x06,0x21,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80, + 0xc0,0x99,0x04,0xd3,0x04,0x03,0x00,0x03,0x00,0x45,0x00,0x49,0x34,0x00,0x00,0x00, + 0x37,0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00, + 0x33,0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00, + 0x33,0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00, + 0x33,0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00, + 0x33,0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00, + 0x33,0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00, + 0x33,0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00, + 0x33,0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00, + 0x33,0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00, + 0x33,0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00, + 0x33,0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00, + 0x33,0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00, + 0x33,0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00, + 0x33,0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00, + 0x33,0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00, + 0x33,0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x37,0x00,0x3e,0x00,0x33,0x00,0x3f,0x00, + 0x37,0x00,0x40,0x00,0x33,0x00,0x41,0x00,0x37,0x00,0x42,0x00,0x36,0x00,0x43,0x00, + 0x39,0x00,0x44,0x00,0x36,0x02,0x40,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00, + 0x0d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x09,0x65,0x76, + 0x61,0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x00,0x0b,0x61,0x63,0x74, + 0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d, + 0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72, + 0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c, + 0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73,0x75,0x62,0x73,0x74, + 0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x00,0x09,0x73,0x71,0x72,0x74,0x00, + 0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64,0x69,0x76,0x00,0x08, + 0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64,0x64,0x00,0x0b,0x72, + 0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73, + 0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08, + 0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e, + 0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a, + 0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64, + 0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01, + 0x00,0x05,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a, + 0x73,0x74,0x6f,0x72,0x65,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02,0x08,0x73, + 0x65,0x74,0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69, + 0x6f,0x6e,0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75, + 0x61,0x67,0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63, + 0x74,0x69,0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a, + 0x22,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d, + 0x65,0x6e,0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22, + 0x63,0x61,0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d, +} diff --git a/contract/vm_multicall.lua b/contract/vm_multicall.lua new file mode 100644 index 000000000..e0ec420f2 --- /dev/null +++ b/contract/vm_multicall.lua @@ -0,0 +1,196 @@ +------------------------------------------------------------------- +-- COMPOSABLE EXECUTION +------------------------------------------------------------------- + +vars = {} + +skip = {store=true,let=true,set=true,insert=true,assert=true} + +action = { + + -- contract call + call = function (...) return contract.call(...) end, + ["call-send"] = function (amount,...) return contract.call.value(amount)(...) end, + ["pcall"] = function (...) return {pcall(contract.call,...)} end, + ["pcall-send"] = function (amount,...) return {pcall(contract.call.value(amount),...)} end, + + -- aergo balance and transfer + balance = function (address) return contract.balance(address) end, + send = function (address,amount) return contract.send(address, amount) end, + + -- variables + let = function (x,y) vars[x] = y end, + store = function (n) vars[n] = vars['last_result'] end, + + -- tables + get = function (o,k) return o[k] end, + set = function (o,k,v) o[k] = v end, + insert = function (...) table.insert(...) end, -- inserts at the end if no pos informed + remove = function (...) table.remove(...) end, + + -- math + add = function (x,y) return x+y end, + sub = function (x,y) return x-y end, + mul = function (x,y) return x*y end, + div = function (x,y) return x/y end, + pow = function (x,y) return x^y end, + mod = function (x,y) return x%y end, + sqrt = function (x) return bignum.sqrt(x) end, -- use pow(0.5) for numbers + + -- strings + format = function (...) return string.format(...) end, -- for concat: ['format','%s%s','%val1%','%val2%'] + substr = function (...) return string.sub(...) end, + find = function (...) return string.match(...) end, + replace = function (...) return string.gsub(...) end, + + -- conversions + tobignum = function (x) return bignum.number(x) end, + tonumber = function (x) return tonumber(x) end, + tostring = function (x) return tostring(x) end, -- bignum to string + tojson = function (x) return json.encode(x) end, + fromjson = function (x) return json.decode(x) end, -- create tables + + -- assertion + assert = function (...) assert(eval(...),"assertion failed: " .. json.encode({...})) end, + +} + +function execute(calls) + + local if_on = true + local if_done = false + + local for_cmdpos + local for_var, for_type + local for_list, for_pos + local for_last, for_increment + + local cmdpos = 1 + while cmdpos <= #calls do + local call = calls[cmdpos] + local args = {} -- use a copy of the list because of loops + for i,v in ipairs(call) do args[i] = v end + + -- process variables + for i,item in ipairs(args) do + if i > 1 and type(item) == 'string' and #item >= 3 and + string.sub(item, 1, 1) == '%' and string.sub(item, -1, -1) == '%' then + local varname = string.sub(item, 2, -2) + if vars[varname] ~= nil then + args[i] = vars[varname] + end + end + end + + -- process the command + local cmd = table.remove(args, 1) + local fn = action[cmd] + if fn and if_on then + local result = fn(unpack(args)) + if not skip[cmd] then + vars['last_result'] = result + end + + -- if elif else end + elseif cmd == "if" then + if_on = eval(unpack(args)) + if_done = if_on + elseif cmd == "elif" then + if if_on then + if_on = false + elseif not if_done then + if_on = eval(unpack(args)) + if_done = if_on + end + elseif cmd == "else" then + if_on = (not if_on) and (not if_done) + elseif cmd == "end" then + if_on = true + + -- for foreach loop + elseif cmd == "foreach" and if_on then + for_cmdpos = cmdpos + for_type = "each" + for_var = args[1] + for_list = args[2] + for_pos = 1 + vars[for_var] = for_list[for_pos] + elseif cmd == "for" and if_on then + for_cmdpos = cmdpos + for_type = "number" + for_var = args[1] + for_last = args[3] + for_increment = args[4] or 1 + vars[for_var] = args[2] + elseif cmd == "loop" and if_on then + if for_type == "each" then + for_pos = for_pos + 1 + if for_pos <= #for_list then + vars[for_var] = for_list[for_pos] + cmdpos = for_cmdpos + end + elseif for_type == "number" then + vars[for_var] = vars[for_var] + for_increment + if (for_increment > 0 and vars[for_var] > for_last) or (for_increment < 0 and vars[for_var] < for_last) then + -- quit loop (continue to the next command) + else + cmdpos = for_cmdpos + end + end + + -- return + elseif cmd == "return" and if_on then + return unpack(args) -- or the array itself + elseif if_on then + assert(false, "command not found: " .. cmd) + end + + cmdpos = cmdpos + 1 + end + +end + +function eval(...) + local args = {...} + local v1 = args[1] + local op = args[2] + local v2 = args[3] + local neg = false + local matches = false + if string.sub(op,1,1) == "!" then + neg = true + op = string.sub(op, 2) + end + if v1 == nil and op ~= "=" then + -- does not match + elseif op == "=" then + matches = v1 == v2 + elseif op == ">" then + matches = v1 > v2 + elseif op == ">=" then + matches = v1 >= v2 + elseif op == "<" then + matches = v1 < v2 + elseif op == "<=" then + matches = v1 <= v2 + elseif op == "match" then + matches = string.match(v1, v2) ~= nil + else + assert(false, "operator not known: " .. op) + end + if neg then matches = not matches end + if #args > 3 then + op = args[4] + local matches2 = eval(unpack(args, 5, #args)) + if op == "and" then + return (matches and matches2) + elseif op == "or" then + return (matches or matches2) + else + assert(false, "operator not known: " .. op) + end + end + return matches +end + +abi.register(execute) diff --git a/state/contract.go b/state/contract.go index f51d233bf..7f5c9f937 100644 --- a/state/contract.go +++ b/state/contract.go @@ -9,6 +9,14 @@ import ( "github.com/golang/protobuf/proto" ) +func (states *StateDB) GetMultiCallState(aid types.AccountID, st *types.State) (*ContractState) { + res := &ContractState{ + State: st, + account: aid, + } + return res +} + func (states *StateDB) OpenContractStateAccount(aid types.AccountID) (*ContractState, error) { st, err := states.GetAccountState(aid) if err != nil { @@ -85,6 +93,11 @@ func (st *ContractState) SetCode(code []byte) error { return nil } +func (st *ContractState) SetMultiCallCode(code []byte) { + // no codeHash means it is not a contract + st.code = code +} + func (st *ContractState) GetCode() ([]byte, error) { if st.code != nil { // already loaded. diff --git a/types/blockchain.pb.go b/types/blockchain.pb.go index 425c3703e..6a31eff26 100644 --- a/types/blockchain.pb.go +++ b/types/blockchain.pb.go @@ -28,6 +28,7 @@ const ( TxType_TRANSFER TxType = 4 TxType_CALL TxType = 5 TxType_DEPLOY TxType = 6 + TxType_MULTICALL TxType = 7 ) var TxType_name = map[int32]string{ @@ -38,6 +39,7 @@ var TxType_name = map[int32]string{ 4: "TRANSFER", 5: "CALL", 6: "DEPLOY", + 7: "MULTICALL", } var TxType_value = map[string]int32{ "NORMAL": 0, @@ -47,6 +49,7 @@ var TxType_value = map[string]int32{ "TRANSFER": 4, "CALL": 5, "DEPLOY": 6, + "MULTICALL": 7, } func (x TxType) String() string { diff --git a/types/transaction.go b/types/transaction.go index e8e77ff92..bb9573af8 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -159,13 +159,18 @@ func (tx *transaction) Validate(chainidhash []byte, isPublic bool) error { if tx.GetBody().GetRecipient() == nil { return ErrTxInvalidRecipient } - case TxType_DEPLOY: + case TxType_DEPLOY, TxType_MULTICALL: if tx.GetBody().GetRecipient() != nil { return ErrTxInvalidRecipient } if len(tx.GetBody().GetPayload()) == 0 { return ErrTxFormatInvalid } + if tx.GetBody().Type == TxType_MULTICALL { + if amount.Cmp(big.NewInt(0)) != 0 { + return ErrTxInvalidAmount + } + } default: return ErrTxInvalidType } From 7c3cff71e2d12d33dbe63dced141267119bd94a3 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Wed, 15 Jun 2022 21:53:25 -0300 Subject: [PATCH 02/49] [brick] add multicall command --- cmd/brick/exec/multicall.go | 114 ++++++++++++++++++++++++++++++++++++ contract/vm_dummy.go | 69 ++++++++++++++++++---- 2 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 cmd/brick/exec/multicall.go diff --git a/cmd/brick/exec/multicall.go b/cmd/brick/exec/multicall.go new file mode 100644 index 000000000..3825ec79e --- /dev/null +++ b/cmd/brick/exec/multicall.go @@ -0,0 +1,114 @@ +package exec + +import ( + "fmt" + + "github.com/rs/zerolog" + + "github.com/aergoio/aergo/cmd/brick/context" + "github.com/aergoio/aergo/contract" + "github.com/aergoio/aergo/types" +) + +func init() { + registerExec(&multicall{}) +} + +type multicall struct{} + +func (c *multicall) Command() string { + return "multicall" +} + +func (c *multicall) Syntax() string { + return fmt.Sprintf("%s %s %s %s", context.AccountSymbol, + context.ContractArgsSymbol, + context.ExpectedErrSymbol, context.ExpectedSymbol) +} + +func (c *multicall) Usage() string { + return fmt.Sprintf("multicall `[call_json_str]` `[expected_error_str]` `[expected_result_str]`") +} + +func (c *multicall) Describe() string { + return "composable call to multiple smart contracts" +} + +func (c *multicall) Validate(args string) error { + + // is chain is loaded? + if context.Get() == nil { + return fmt.Errorf("load chain first") + } + + _, _, _, _, err := c.parse(args) + + return err +} + +func (c *multicall) parse(args string) (string, string, string, string, error) { + splitArgs := context.SplitSpaceAndAccent(args, false) + if len(splitArgs) < 2 { + return "", "", "", "", fmt.Errorf("need at least 2 arguments. usage: %s", c.Usage()) + } + + callCode := splitArgs[1].Text + expectedError := "" + expectedRes := "" + + if len(splitArgs) >= 3 { + expectedError = splitArgs[2].Text + } + if len(splitArgs) == 4 { + expectedRes = splitArgs[3].Text + } else if len(splitArgs) > 4 { + return "", "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) + } + + return splitArgs[0].Text, //accountName + callCode, + expectedError, + expectedRes, + nil +} + +func (c *multicall) Run(args string) (string, uint64, []*types.Event, error) { + + accountName, payload, expectedError, expectedRes, _ := c.parse(args) + + multicallTx := contract.NewLuaTxMultiCall(accountName, payload) + + logLevel := zerolog.GlobalLevel() + + if expectedError != "" { + multicallTx.Fail(expectedError) + zerolog.SetGlobalLevel(zerolog.ErrorLevel) // turn off log + } + err := context.Get().ConnectBlock(multicallTx) + + if expectedError != "" { + zerolog.SetGlobalLevel(logLevel) // restore log level + } + if err != nil { + return "", 0, nil, err + } + + if expectedError != "" { + Index(context.ExpectedErrSymbol, expectedError) + return "call a smart contract successfully", 0, nil, nil + } + + receipt := context.Get().GetReceipt(multicallTx.Hash()) + + if expectedRes != "" && expectedRes != receipt.Ret { + err = fmt.Errorf("expected: %s, but got: %s", expectedRes, receipt.Ret) + return "", 0, nil, err + } + + result := "success" + if expectedRes == "" && len(receipt.Ret) > 0 { + result += ": " + receipt.Ret + } + return result, receipt.GasUsed, context.Get().GetEvents(multicallTx.Hash()), nil + +} diff --git a/contract/vm_dummy.go b/contract/vm_dummy.go index fe3218fa8..b0b021049 100644 --- a/contract/vm_dummy.go +++ b/contract/vm_dummy.go @@ -294,6 +294,7 @@ type luaTxContract interface { amount() *big.Int code() []byte isFeeDelegate() bool + isMultiCall() bool } type luaTxContractCommon struct { @@ -303,6 +304,7 @@ type luaTxContractCommon struct { _code []byte txId uint64 feeDelegate bool + multiCall bool } func (l *luaTxContractCommon) Hash() []byte { @@ -329,6 +331,10 @@ func (l *luaTxContractCommon) isFeeDelegate() bool { return l.feeDelegate } +func (l *luaTxContractCommon) isMultiCall() bool { + return l.multiCall +} + func hash(id uint64) []byte { h := sha256.New() h.Write([]byte(strconv.FormatUint(id, 10))) @@ -390,15 +396,27 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb ChainAccessor, rec } contractId := types.ToAccountID(l.contract()) - contractState, err := bs.GetAccountStateV(l.contract()) + + var contractState *state.V + if l.isMultiCall() { + contractState = creatorState + } else { + contractState, err = bs.GetAccountStateV(l.contract()) + } if err != nil { return err } - eContractState, err := bs.OpenContractState(contractId, contractState.State()) + var eContractState *state.ContractState + if l.isMultiCall() { + eContractState = bs.GetMultiCallState(creatorId, creatorState.State()) + } else { + eContractState, err = bs.OpenContractState(contractId, contractState.State()) + } if err != nil { return err } + usedFee := txFee(len(l.code()), new(big.Int).SetUint64(1), 2) if l.isFeeDelegate() { @@ -417,9 +435,14 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb ChainAccessor, rec return types.ErrNotAllowedFeeDelegation } } - creatorState.SubBalance(l.amount()) - contractState.AddBalance(l.amount()) + + if contractId != creatorId { + creatorState.SubBalance(l.amount()) + contractState.AddBalance(l.amount()) + } + rv, evs, cFee, err := run(creatorState, contractState, contractId, eContractState) + if cFee != nil { usedFee.Add(usedFee, cFee) } @@ -428,6 +451,7 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb ChainAccessor, rec status = "ERROR" rv = err.Error() } + r := types.NewReceipt(l.contract(), status, rv) r.TxHash = l.Hash() r.GasUsed = usedFee.Uint64() @@ -454,10 +478,13 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb ChainAccessor, rec } creatorState.SubBalance(usedFee) } + bs.PutState(creatorId, creatorState.State()) - bs.PutState(contractId, contractState.State()) - return nil + if contractId != creatorId { + bs.PutState(contractId, contractState.State()) + } + return nil } func (l *luaTxDef) run(bs *state.BlockState, bc *DummyChain, bi *types.BlockHeaderInfo, receiptTx db.Transaction) error { @@ -469,7 +496,7 @@ func (l *luaTxDef) run(bs *state.BlockState, bc *DummyChain, bi *types.BlockHead contract.State().SqlRecoveryPoint = 1 ctx := newVmContext(bs, nil, sender, contract, eContractState, sender.ID(), l.Hash(), bi, "", true, - false, contract.State().SqlRecoveryPoint, BlockFactory, l.amount(), math.MaxUint64, false) + false, contract.State().SqlRecoveryPoint, BlockFactory, l.amount(), math.MaxUint64, false, false) if traceState { ctx.traceFile, _ = @@ -526,6 +553,19 @@ func NewLuaTxCallFeeDelegate(sender, contract string, amount uint64, code string } } +func NewLuaTxMultiCall(sender, code string) *luaTxCall { + return &luaTxCall{ + luaTxContractCommon: luaTxContractCommon{ + _sender: strHash(sender), + _contract: strHash(""), + _amount: new(big.Int).SetUint64(0), + _code: []byte(code), + txId: newTxId(), + multiCall: true, + }, + } +} + func (l *luaTxCall) Fail(expectedErr string) *luaTxCall { l.expectedErr = expectedErr return l @@ -534,21 +574,28 @@ func (l *luaTxCall) Fail(expectedErr string) *luaTxCall { func (l *luaTxCall) run(bs *state.BlockState, bc *DummyChain, bi *types.BlockHeaderInfo, receiptTx db.Transaction) error { err := contractFrame(l, bs, bc, receiptTx, func(sender, contract *state.V, contractId types.AccountID, eContractState *state.ContractState) (string, []*types.Event, *big.Int, error) { + ctx := newVmContext(bs, bc, sender, contract, eContractState, sender.ID(), l.Hash(), bi, "", true, - false, contract.State().SqlRecoveryPoint, BlockFactory, l.amount(), math.MaxUint64, l.feeDelegate) + false, contract.State().SqlRecoveryPoint, BlockFactory, l.amount(), math.MaxUint64, l.feeDelegate, l.multiCall) + if traceState { ctx.traceFile, _ = os.OpenFile("test.trace", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) defer ctx.traceFile.Close() } + rv, evs, ctrFee, err := Call(eContractState, l.code(), l.contract(), ctx) if err != nil { return "", nil, ctrFee, err } - err = bs.StageContractState(eContractState) - if err != nil { - return "", nil, ctrFee, err + + if !ctx.isMultiCall { + err = bs.StageContractState(eContractState) + if err != nil { + return "", nil, ctrFee, err + } } + return rv, evs, ctrFee, nil }, ) From 001cac167cce1cffc4a30e8057f14668c4110441 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Thu, 16 Jun 2022 05:06:16 -0300 Subject: [PATCH 03/49] [contract] add tests for composable transactions --- contract/vm_test.go | 1066 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1066 insertions(+) diff --git a/contract/vm_test.go b/contract/vm_test.go index 2be0abddf..1a8a949dd 100644 --- a/contract/vm_test.go +++ b/contract/vm_test.go @@ -6155,4 +6155,1070 @@ abi.register(stmt_exec, stmt_exec_pcall, get)` } } + +////////////////////////////////////////////////////////////////////// +// COMPOSABLE TRANSACTIONS +////////////////////////////////////////////////////////////////////// + +func multicall(t *testing.T, bc *DummyChain, params ...string) { + var expectedError, expectedResult string + account := params[0] + payload := params[1] + if len(params) > 2 { + expectedError = params[2] + } + if len(params) > 3 { + expectedResult = params[3] + } + + tx := NewLuaTxMultiCall(account, payload).Fail(expectedError) + + err := bc.ConnectBlock(tx) + if err != nil { + t.Error(err) + } + + if expectedError == "" && expectedResult != "" { + receipt := bc.GetReceipt(tx.Hash()) + if receipt.GetRet() != expectedResult { + t.Errorf("multicall invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) + } + } + +} + +func call(t *testing.T, bc *DummyChain, + account string, amount uint64, + contract string, function string, args string, + expectedError string, expectedResult string) { + + callinfo := fmt.Sprintf(`{"Name":"%s", "Args":%s}`, function, args) + + tx := NewLuaTxCall(account, contract, amount, callinfo).Fail(expectedError) + + err := bc.ConnectBlock(tx) + if err != nil { + t.Error(err) + } + + if expectedError == "" && expectedResult != "" { + receipt := bc.GetReceipt(tx.Hash()) + if receipt.GetRet() != expectedResult { + t.Errorf("call invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) + } + } + +} + +func TestComposableTransactions(t *testing.T) { + bc, err := LoadDummyChain() + if err != nil { + t.Errorf("failed to create test database: %v", err) + } + defer bc.Release() + + definition := ` +state.var { + name = state.value(), + last = state.value(), + dict = state.map() +} + +function get_dict() + return {one = 1, two = 2, three = 3} +end + +function get_list() + return {'first', 'second', 'third', 123, 12.5, true} +end + +function get_table() + return { name = "Test", second = 'Te"st', number = 123, bool = true, array = {11,22,33} } +end + +function works() + return 123 +end + +function fails() + assert(false, "this call should fail") +end + +function hello(name) + return 'hello ' .. name +end + +function set_name(val) + name:set(val) + assert(type(val)=='string', "must be string") +end + +function get_name() + return name:get() +end + +function set(key, value) + dict[key] = value +end + +function add(value) + local key = (last:get() or 0) + 1 + dict[tostring(key)] = value + last:set(key) +end + +function get(key) + return dict[key] +end + +abi.register(add, set, set_name) +abi.register_view(get_dict, get_list, get_table, works, fails, get, get_name, hello) + +function call(...) + return contract.call(...) +end + +function is_contract(address) + return system.isContract(address) +end + +function sender() + return system.getSender() +end + +function origin() + return system.getOrigin() +end + +abi.register(call) +abi.register_view(is_contract, sender, origin) + +function recv_aergo() + -- does nothing +end + +abi.payable(recv_aergo) +` + + err = bc.ConnectBlock( + NewLuaTxAccount("ac0", 10000000000000000000), + NewLuaTxAccount("ac1", 10000000000000000000), + NewLuaTxAccount("ac2", 10000000000000000000), + NewLuaTxAccount("ac3", 10000000000000000000), + NewLuaTxAccount("ac4", 10000000000000000000), + NewLuaTxAccount("ac5", 10000000000000000000), + NewLuaTxDef("ac0", "tables", 0, definition), + NewLuaTxDef("ac0", "c1", 0, definition), + NewLuaTxDef("ac0", "c2", 0, definition), + NewLuaTxDef("ac0", "c3", 0, definition), + ) + if err != nil { + t.Error(err) + } + + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_dict"], + ["store","dict"], + ["set","%dict%","two",22], + ["set","%dict%","four",4], + ["set","%dict%","one",null], + ["get","%dict%","two"], + ["set","%dict%","copy","%last_result%"], + ["return","%dict%"] + ]`, ``, `{"copy":22,"four":4,"three":3,"two":22}`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], + ["store","array"], + ["set","%array%",2,"2nd"], + ["insert","%array%",1,"zero"], + ["insert","%array%","last"], + ["return","%array%"] + ]`, ``, `["zero","first","2nd","third",123,12.5,true,"last"]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], + ["store","array"], + ["remove","%array%",3], + ["return","%array%"] + ]`, ``, `["first","second",123,12.5,true]`) + + + // create new dict or array using fromjson + + multicall(t, bc, "ac1", `[ + ["fromjson","{\"one\":1,\"two\":2}"], + ["set","%last_result%","three",3], + ["return","%last_result%"] + ]`, ``, `{"one":1,"three":3,"two":2}`) + + + // define dict or list using let + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2}], + ["set","%obj%","three",3], + ["return","%obj%"] + ]`, ``, `{"one":1,"three":3,"two":2}`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["set","%list%",4,"three"], + ["insert","%list%",1,"first"], + ["insert","%list%","last"], + ["return","%list%"] + ]`, ``, `["first","one",1,"two","three",2.5,true,false,"last"]`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",22,3.3,true,false]], + ["get","%list%",1], + ["assert","%last_result%","=","one"], + ["get","%list%",2], + ["assert","%last_result%","=",22], + ["get","%list%",3], + ["assert","%last_result%","=",3.3], + ["get","%list%",4], + ["assert","%last_result%","=",true], + ["get","%list%",5], + ["assert","%last_result%","=",false], + ["return","%list%"] + ]`, ``, `["one",22,3.3,true,false]`) + + + + // BIGNUM + + multicall(t, bc, "ac1", `[ + ["tobignum",123], + ["store","a"], + ["tobignum",123], + ["store","b"], + ["mul","%a%","%b%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"15129"}`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","100000"], + ["store","b"], + ["div","%a%","%b%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"5000000000000000"}`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","100000"], + ["store","b"], + ["div","%a%","%b%"], + ["tostring","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"5000000000000000"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + + ["tobignum","100000"], + ["div","%a%","%last_result%"], + ["store","a"], + + ["tobignum","1000000000000000"], + ["sub","%a%","%last_result%"], + ["store","a"], + + ["tobignum","1234"], + ["add","%a%","%last_result%"], + ["store","a"], + + ["tobignum","2"], + ["pow","%a%","%last_result%"], + ["sqrt","%last_result%"], + ["store","a"], + + ["tobignum","2"], + ["mod","%a%","10000"], + + ["return","%last_result%"] + ]`, ``, `{"_bignum":"1234"}`) + + multicall(t, bc, "ac1", `[ + ["let","a",25], + ["sqrt","%a%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"5"}`) + + multicall(t, bc, "ac1", `[ + ["let","a",25], + ["pow","%a%",0.5], + ["return","%last_result%"] + ]`, ``, `5`) + + + + // STRINGS + + multicall(t, bc, "ac1", `[ + ["format","%s%s%s","hello"," ","world"], + ["return","%last_result%"] + ]`, ``, `"hello world"`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["substr","%s%",1,4], + ["return","%last_result%"] + ]`, ``, `"hell"`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["substr","%s%",-2,-1], + ["return","%last_result%"] + ]`, ``, `"ld"`) + + multicall(t, bc, "ac1", `[ + ["let","s","the amount is 12345"], + ["find","%s%","%d+"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `12345`) + + multicall(t, bc, "ac1", `[ + ["let","s","rate: 55 10%"], + ["find","%s%","(%d+)%%"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `10`) + + multicall(t, bc, "ac1", `[ + ["let","s","rate: 12%"], + ["find","%s%","%s*(%d+)%%"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `12`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["replace","%s%","hello","good bye"], + ["return","%last_result%"] + ]`, ``, `"good bye world"`) + + multicall(t, bc, "ac1", `[ + ["fromjson","{\"name\":\"ticket\",\"value\":12.5,\"amount\":10}"], + ["replace","name = $name, value = $value, amount = $amount","%$(%w+)","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"name = ticket, value = 12.5, amount = 10"`) + + + // IF THEN ELSE + + multicall(t, bc, "ac1", `[ + ["let","s",20], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["big","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",10], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["medium","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",5], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["low","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",20], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"big"`) + + multicall(t, bc, "ac1", `[ + ["let","s",10], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"medium"`) + + multicall(t, bc, "ac1", `[ + ["let","s",5], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"low"`) + + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000000"], + ["store","b"], + ["if","%a%","=","%b%"], + ["let","b","equal"], + ["else"], + ["let","b","diff"], + ["end"], + ["return","%b%"] + ]`, ``, `"equal"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","=","%b%"], + ["let","b","equal"], + ["else"], + ["let","b","diff"], + ["end"], + ["return","%b%"] + ]`, ``, `"diff"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000001"], + ["store","a"], + ["tobignum","500000000000000000000"], + ["store","b"], + ["if","%a%",">","%b%"], + ["let","b","bigger"], + ["else"], + ["let","b","lower"], + ["end"], + ["return","%b%"] + ]`, ``, `"bigger"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%",">","%b%"], + ["let","b","bigger"], + ["else"], + ["let","b","lower"], + ["end"], + ["return","%b%"] + ]`, ``, `"lower"`) + + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","<","%b%","and","1","=","0"], + ["let","b","wrong 1"], + ["elif","%a%","<","%b%","and","1","=","1"], + ["let","b","correct"], + ["else"], + ["let","b","wrong 2"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","<","%b%","and",1,"=",0], + ["let","b","wrong 1"], + ["elif","%a%","<","%b%","and",1,"=",1], + ["let","b","correct"], + ["else"], + ["let","b","wrong 2"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["tobignum","400000000000000000000"], + ["store","c"], + ["if","%a%","<","%b%","and","%a%","<","%c%"], + ["let","b","wrong 1"], + ["elif","%a%",">","%b%","and","%a%",">","%c%"], + ["let","b","wrong 2"], + ["elif","%a%","<","%b%","and","%a%",">","%c%"], + ["let","b","correct"], + ["else"], + ["let","b","wrong 3"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["tobignum","400000000000000000000"], + ["store","c"], + ["tostring",0], + + ["if","%a%",">","%b%","or","%a%","<","%c%"], + ["format","%s%s","%last_result%","1"], + ["end"], + + ["if","%a%","=","%b%","or","%a%","=","%c%"], + ["format","%s%s","%last_result%","2"], + ["end"], + + ["if","%a%","<","%b%","or","%a%","<","%c%"], + ["format","%s%s","%last_result%","3"], + ["end"], + + ["if","%a%",">","%b%","or","%a%",">","%c%"], + ["format","%s%s","%last_result%","4"], + ["end"], + + ["if","%a%","<","%b%","or","%a%",">","%c%"], + ["format","%s%s","%last_result%","5"], + ["end"], + + ["if","%a%","!=","%b%","or","%a%","=","%c%"], + ["format","%s%s","%last_result%","6"], + ["end"], + + ["if","%a%","=","%b%","or","%a%","!=","%c%"], + ["format","%s%s","%last_result%","7"], + ["end"], + + + ["if","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","8"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","9"], + ["end"], + + ["if","%b%",">=","%a%","and","%b%","<=","%c%"], + ["format","%s%s","%last_result%","A"], + ["end"], + + ["if","%b%",">=","%c%","and","%b%","<=","%a%"], + ["format","%s%s","%last_result%","B"], + ["end"], + + ["if","%c%",">=","%a%","and","%c%","<=","%b%"], + ["format","%s%s","%last_result%","C"], + ["end"], + + ["if","%c%",">=","%b%","and","%c%","<=","%a%"], + ["format","%s%s","%last_result%","D"], + ["end"], + + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",0], + ["format","%s%s","%last_result%","E"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",1], + ["format","%s%s","%last_result%","F"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",0], + ["format","%s%s","%last_result%","G"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",1], + ["format","%s%s","%last_result%","H"], + ["end"], + + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",0], + ["format","%s%s","%last_result%","I"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",1], + ["format","%s%s","%last_result%","J"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",0], + ["format","%s%s","%last_result%","K"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",1], + ["format","%s%s","%last_result%","L"], + ["end"], + + + ["if",1,"=",0,"or","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","M"], + ["end"], + + ["if",1,"=",1,"or","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","N"], + ["end"], + + ["if",1,"=",0,"or","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","O"], + ["end"], + + ["if",1,"=",1,"or","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","P"], + ["end"], + + + ["return","%last_result%"] + ]`, ``, `"0345679IJLNOP"`) + + + + + // FOR + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["loop"], + ["return","%n%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tobignum","10000000000000000001"], + ["store","to_add"], + ["tobignum","100000000000000000000"], + + ["for","n",1,3], + ["add","%last_result%","%to_add%"], + ["loop"], + + ["tostring","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"130000000000000000003"`) + + + // FOR "BREAK" + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["if","%n%","=",5], + ["let","n",500], + ["end"], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["let","c",0], + ["for","n",1,10], + ["add","%last_result%",1], + ["if","%n%","=",5], + ["let","n",500], + ["end"], + ["loop"], + ["return","%last_result%"] + ]`, ``, `5`) + + + // FOREACH + + multicall(t, bc, "ac1", `[ + ["let","list",[11,22,33]], + ["let","r",0], + ["foreach","item","%list%"], + ["add","%r%","%item%"], + ["store","r"], + ["loop"], + ["return","%r%"] + ]`, ``, `66`) + + multicall(t, bc, "ac1", `[ + ["let","list",[10,21,32]], + ["let","r",0], + ["foreach","item","%list%"], + ["if","%item%","<",30], + ["add","%r%","%item%"], + ["store","r"], + ["end"], + ["loop"], + ["return","%r%"] + ]`, ``, `31`) + + + // RETURN before the end + + multicall(t, bc, "ac1", `[ + ["let","v",123], + ["if","%v%",">",100], + ["return"], + ["end"], + ["let","v",500], + ["return","%v%"] + ]`, ``, ``) + + multicall(t, bc, "ac1", `[ + ["let","v",123], + ["if","%v%",">",200], + ["return"], + ["end"], + ["let","v",500], + ["return","%v%"] + ]`, ``, `500`) + + + + // CALLS + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["assert","%last_result%","=",123], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["return","%last_result%"] + ]`, ``, `123`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"] + ]`, `this call should fail`) + + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","test"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","test"] + ]`) + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","wrong"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","wrong"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",123] + ]`, `must be string`) + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","test"], + ["return","%last_result%"] + ]`, ``, `"test"`) + + + multicall(t, bc, "ac3", `[ + ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], + ["call","%c%","set_name","test2"], + ["call","%c%","get_name"], + ["assert","%last_result%","=","test2"] + ]`) + + + // CALL LOOP + + multicall(t, bc, "ac3", `[ + ["let","list",["first","second","third"]], + ["foreach","item","%list%"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","add","%item%"], + ["loop"] + ]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], + ["assert","%last_result%","=","first"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], + ["assert","%last_result%","=","second"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], + ["assert","%last_result%","=","third"] + ]`) + + multicall(t, bc, "ac3", `[ + ["let","list",["1st","2nd","3rd"]], + ["let","n",1], + ["foreach","item","%list%"], + ["tostring","%n%"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set","%last_result%","%item%"], + ["add","%n%",1], + ["store","n"], + ["loop"] + ]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], + ["assert","%last_result%","=","1st"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], + ["assert","%last_result%","=","2nd"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], + ["assert","%last_result%","=","3rd"] + ]`) + + + + // PCALL + + multicall(t, bc, "ac1", `[ + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["get","%last_result%",1], + ["assert","%last_result%","=",true], + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"], + ["get","%last_result%",1], + ["assert","%last_result%","=",false] + ]`) + + multicall(t, bc, "ac3", `[ + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","1st"], + ["get","%last_result%",1], + ["assert","%last_result%","=",true], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["store","ret"], + ["get","%ret%",1], + ["assert","%last_result%","=",true], + ["get","%ret%",2], + ["assert","%last_result%","=","1st"], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",22], + ["get","%last_result%",1], + ["assert","%last_result%","=",false], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["store","ret"], + ["get","%ret%",1], + ["assert","%last_result%","=",true], + ["get","%ret%",2], + ["assert","%last_result%","=","1st"], + + ["return","%last_result%"] + ]`, ``, `"1st"`) + + + + // MULTICALL ON ACCOUNT ------------------------------------------ + + + //deploy ac0 0 c1 test.lua + //deploy ac0 0 c2 test.lua + //deploy ac0 0 c3 test.lua + + // c1: AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9 + // c2: Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4 + // c3: AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","testing multicall"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","contract 2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","third one"] + ]`) + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["assert","%last_result%","=","testing multicall"], + ["store","r1"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["assert","%last_result%","=","contract 2"], + ["store","r2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["assert","%last_result%","=","third one"], + ["store","r3"], + ["return","%r1%","%r2%","%r3%"] + ]`, ``, `["testing multicall","contract 2","third one"]`) + + multicall(t, bc, "ac0", `[ + ["fromjson","{}"], + ["store","res"], + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["set","%res%","r1","%last_result%"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["set","%res%","r2","%last_result%"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["set","%res%","r3","%last_result%"], + ["return","%res%"] + ]`, ``, `{"r1":"testing multicall","r2":"contract 2","r3":"third one"}`) + + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","wohooooooo"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","it works!"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","it really works!"] + ]`) + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["assert","%last_result%","=","wohooooooo"], + ["store","r1"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["assert","%last_result%","=","it works!"], + ["store","r2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["assert","%last_result%","=","it really works!"], + ["store","r3"], + ["return","%r1%","%r2%","%r3%"] + ]`, ``, `["wohooooooo","it works!","it really works!"]`) + + multicall(t, bc, "ac0", `[ + ["fromjson","{}"], + ["store","res"], + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["set","%res%","r1","%last_result%"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["set","%res%","r2","%last_result%"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["set","%res%","r3","%last_result%"], + ["return","%res%"] + ]`, ``, `{"r1":"wohooooooo","r2":"it works!","r3":"it really works!"}`) + + + + // aergo balance and send + + multicall(t, bc, "ac5", `[ + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","10000000000000000000"], + ["return","%last_result%"] + ]`, ``, `"10000000000000000000"`) + + multicall(t, bc, "ac2", `[ + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","10000000000000000000"], + + ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","0"], + + ["send","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc","3000000000000000000"], + + ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","3000000000000000000"], + + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","7000000000000000000"], + + ["return","%last_result%"] + ]`, ``, `"7000000000000000000"`) + + + + // SECURITY CHECKS + + // it should not be possible to call the code from another account + + // a. from an account (via multicall, using the 'call' command) + + multicall(t, bc, "ac1", `[ + ["call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) + + + // b. from an account (via a call tx) + + call(t, bc, "ac1", 0, "ac1", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + + call(t, bc, "ac1", 0, "ac2", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + + + // c. from a contract (calling back) + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) + + + // d. from a contract (calling another account) + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) + + + // e. from a contract (via a call txn) + + call(t, bc, "ac1", 0, "c2", "call", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + + call(t, bc, "ac1", 0, "c2", "call", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + + + // system.isContract() should return false on user accounts + + call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"]`, ``, `false`) + + call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"]`, ``, `false`) + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"], + ["assert","%last_result%","=",false], + ["return","%last_result%"] + ]`, ``, `false`) + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"], + ["assert","%last_result%","=",false], + ["return","%last_result%"] + ]`, ``, `false`) + + + // on a contract called by multicall, the system.getSender() and system.getOrigin() must be the same + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","sender"], + ["store","sender"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","origin"], + ["store","origin"], + ["assert","%sender%","=","%origin%"], + ["return","%sender%"] + ]`, ``, `"AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"`) + + +} + // end of test-cases From 67322afe651024b7811d14c978195eb9ecfdd6d5 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Fri, 24 Jun 2022 00:25:01 -0300 Subject: [PATCH 04/49] [brick] update multicall command --- cmd/brick/context/symbol.go | 2 ++ cmd/brick/exec/multicall.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/brick/context/symbol.go b/cmd/brick/context/symbol.go index a3b9b13d3..22e59f28d 100644 --- a/cmd/brick/context/symbol.go +++ b/cmd/brick/context/symbol.go @@ -7,6 +7,7 @@ var ( AccountSymbol = "" AmountSymbol = "" ContractArgsSymbol = "" + MulticallSymbol = "" ExpectedSymbol = "" ExpectedErrSymbol = "" FunctionSymbol = "" @@ -21,6 +22,7 @@ func init() { Symbols[ContractSymbol] = "contract address" Symbols[AccountSymbol] = "account address" Symbols[ContractArgsSymbol] = "an array of argments to call a contract" + Symbols[MulticallSymbol] = "a list of commands in JSON" Symbols[AmountSymbol] = "amount of aergo to send" Symbols[ExpectedSymbol] = "expected result" Symbols[ExpectedErrSymbol] = "expected error" diff --git a/cmd/brick/exec/multicall.go b/cmd/brick/exec/multicall.go index 3825ec79e..d3d1a00f6 100644 --- a/cmd/brick/exec/multicall.go +++ b/cmd/brick/exec/multicall.go @@ -22,12 +22,12 @@ func (c *multicall) Command() string { func (c *multicall) Syntax() string { return fmt.Sprintf("%s %s %s %s", context.AccountSymbol, - context.ContractArgsSymbol, + context.MulticallSymbol, context.ExpectedErrSymbol, context.ExpectedSymbol) } func (c *multicall) Usage() string { - return fmt.Sprintf("multicall `[call_json_str]` `[expected_error_str]` `[expected_result_str]`") + return fmt.Sprintf("multicall `[commands_json_str]` `[expected_error_str]` `[expected_result_str]`") } func (c *multicall) Describe() string { From 08da940d99e8a520b2ba08cef2440da7af1cb2a4 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 25 Jun 2022 18:03:29 -0300 Subject: [PATCH 05/49] [contract] update composable transactions --- contract/vm_multicall.go | 440 +++++++++++++++++++++----------------- contract/vm_multicall.lua | 68 ++++-- 2 files changed, 303 insertions(+), 205 deletions(-) diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go index f353a1df3..0c96e4973 100644 --- a/contract/vm_multicall.go +++ b/contract/vm_multicall.go @@ -1,7 +1,7 @@ package contract var multicall_payload = []byte { - 0xd4,0x0c,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, + 0x51,0x10,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, 0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00, 0x00,0x00,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, 0x37,0x02,0x01,0x04,0x00,0x03,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, @@ -22,195 +22,251 @@ var multicall_payload = []byte { 0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x29,0x00,0x02,0x06,0x00,0x02,0x00,0x05,0x36, 0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x12,0x04,0x00,0x00,0x12,0x05,0x01,0x00,0x44, 0x02,0x03,0x00,0x09,0x73,0x65,0x6e,0x64,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63, - 0x74,0x18,0x00,0x02,0x03,0x00,0x01,0x00,0x03,0x36,0x02,0x00,0x00,0x3c,0x01,0x00, - 0x02,0x4b,0x00,0x01,0x00,0x09,0x76,0x61,0x72,0x73,0x2c,0x00,0x01,0x03,0x00,0x02, - 0x00,0x05,0x36,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x3c,0x02, - 0x00,0x01,0x4b,0x00,0x01,0x00,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75, - 0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x38, - 0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x03,0x03,0x00,0x00,0x00,0x02,0x3c, - 0x02,0x01,0x00,0x4b,0x00,0x01,0x00,0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36, - 0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b, - 0x00,0x01,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65, - 0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00, - 0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x72,0x65,0x6d, - 0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x20,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x21,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x22,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x23,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x25,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00, - 0x02,0x24,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x23,0x00,0x01,0x04,0x00,0x02,0x00, - 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, - 0x00,0x09,0x73,0x71,0x72,0x74,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x25,0x02,0x00, - 0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00, - 0x00,0x43,0x00,0x00,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72, - 0x69,0x6e,0x67,0x22,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39, - 0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b, - 0x73,0x74,0x72,0x69,0x6e,0x67,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00, - 0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d, - 0x61,0x74,0x63,0x68,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00, - 0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43, - 0x00,0x00,0x00,0x09,0x67,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25, - 0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12, - 0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62, - 0x69,0x67,0x6e,0x75,0x6d,0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00, - 0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62, - 0x65,0x72,0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03, - 0x00,0x00,0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23, - 0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12, - 0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a, - 0x73,0x6f,0x6e,0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39, - 0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f, - 0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36, - 0x00,0x00,0x00,0x36,0x02,0x01,0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27, - 0x03,0x02,0x00,0x36,0x04,0x03,0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47, - 0x07,0x00,0x00,0x3f,0x07,0x00,0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42, - 0x00,0x03,0x01,0x4b,0x00,0x01,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a, - 0x73,0x6f,0x6e,0x17,0x61,0x73,0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61, - 0x69,0x6c,0x65,0x64,0x3a,0x20,0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65, - 0x72,0x74,0x03,0x80,0x80,0xc0,0x99,0x04,0x80,0x08,0x00,0x01,0x17,0x00,0x19,0x01, - 0xd6,0x01,0x2b,0x01,0x02,0x00,0x2b,0x02,0x01,0x00,0x2c,0x03,0x09,0x00,0x29,0x0a, - 0x01,0x00,0x15,0x0b,0x00,0x00,0x03,0x0a,0x0b,0x00,0x58,0x0b,0xce,0x80,0x55,0x0b, - 0xcd,0x80,0x38,0x0b,0x0a,0x00,0x34,0x0c,0x00,0x00,0x36,0x0d,0x00,0x00,0x12,0x0f, - 0x0b,0x00,0x42,0x0d,0x02,0x04,0x58,0x10,0x01,0x80,0x3c,0x11,0x10,0x0c,0x45,0x10, - 0x03,0x03,0x52,0x10,0xfd,0x7f,0x36,0x0d,0x00,0x00,0x12,0x0f,0x0c,0x00,0x42,0x0d, - 0x02,0x04,0x58,0x10,0x29,0x80,0x29,0x12,0x01,0x00,0x01,0x12,0x10,0x00,0x58,0x12, - 0x26,0x80,0x36,0x12,0x01,0x00,0x12,0x14,0x11,0x00,0x42,0x12,0x02,0x02,0x07,0x12, - 0x02,0x00,0x58,0x12,0x21,0x80,0x15,0x12,0x11,0x00,0x29,0x13,0x03,0x00,0x03,0x13, - 0x12,0x00,0x58,0x12,0x1d,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, - 0x11,0x00,0x29,0x15,0x01,0x00,0x29,0x16,0x01,0x00,0x42,0x12,0x04,0x02,0x07,0x12, - 0x04,0x00,0x58,0x12,0x15,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, - 0x11,0x00,0x29,0x15,0xff,0xff,0x29,0x16,0xff,0xff,0x42,0x12,0x04,0x02,0x07,0x12, - 0x04,0x00,0x58,0x12,0x0d,0x80,0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14, - 0x11,0x00,0x29,0x15,0x02,0x00,0x29,0x16,0xfe,0xff,0x42,0x12,0x04,0x02,0x36,0x13, - 0x05,0x00,0x38,0x13,0x12,0x13,0x0a,0x13,0x00,0x00,0x58,0x13,0x03,0x80,0x36,0x13, - 0x05,0x00,0x38,0x13,0x12,0x13,0x3c,0x13,0x10,0x0c,0x45,0x10,0x03,0x03,0x52,0x10, - 0xd5,0x7f,0x36,0x0d,0x06,0x00,0x39,0x0d,0x07,0x0d,0x12,0x0f,0x0c,0x00,0x29,0x10, - 0x01,0x00,0x42,0x0d,0x03,0x02,0x36,0x0e,0x08,0x00,0x38,0x0e,0x0d,0x0e,0x0f,0x00, - 0x0e,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x0f, - 0x0e,0x00,0x36,0x11,0x09,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f, - 0x00,0x02,0x36,0x10,0x0a,0x00,0x38,0x10,0x0d,0x10,0x0e,0x00,0x10,0x00,0x58,0x10, - 0x7f,0x80,0x36,0x10,0x05,0x00,0x3d,0x0f,0x0b,0x10,0x58,0x0f,0x7c,0x80,0x07,0x0d, - 0x0c,0x00,0x58,0x0f,0x08,0x80,0x36,0x0f,0x0d,0x00,0x36,0x11,0x09,0x00,0x12,0x13, - 0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02, - 0x01,0x00,0x58,0x0f,0x72,0x80,0x07,0x0d,0x0e,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00, - 0x01,0x00,0x58,0x0f,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x6c,0x80,0x0e,0x00, - 0x02,0x00,0x58,0x0f,0x6a,0x80,0x36,0x0f,0x0d,0x00,0x36,0x11,0x09,0x00,0x12,0x13, - 0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02, - 0x01,0x00,0x58,0x0f,0x62,0x80,0x07,0x0d,0x0f,0x00,0x58,0x0f,0x08,0x80,0x0e,0x00, - 0x01,0x00,0x58,0x0f,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x0f,0x5c,0x80,0x2b,0x01, - 0x01,0x00,0x58,0x0f,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x58,0x80,0x07,0x0d, - 0x10,0x00,0x58,0x0f,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x54,0x80,0x07,0x0d, - 0x11,0x00,0x58,0x0f,0x0b,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x09,0x80,0x12,0x03, - 0x0a,0x00,0x27,0x05,0x12,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x06,0x02,0x0c,0x29,0x07, - 0x01,0x00,0x36,0x0f,0x05,0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04,0x0f,0x58,0x0f, - 0x47,0x80,0x07,0x0d,0x13,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f, - 0x0c,0x80,0x12,0x03,0x0a,0x00,0x27,0x05,0x14,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x08, - 0x03,0x0c,0x3a,0x0f,0x04,0x0c,0x0c,0x09,0x0f,0x00,0x58,0x10,0x01,0x80,0x29,0x09, - 0x01,0x00,0x36,0x0f,0x05,0x00,0x3a,0x10,0x02,0x0c,0x3c,0x10,0x04,0x0f,0x58,0x0f, - 0x37,0x80,0x07,0x0d,0x15,0x00,0x58,0x0f,0x25,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f, - 0x23,0x80,0x07,0x05,0x12,0x00,0x58,0x0f,0x09,0x80,0x16,0x07,0x00,0x07,0x15,0x0f, - 0x06,0x00,0x03,0x07,0x0f,0x00,0x58,0x0f,0x2d,0x80,0x36,0x0f,0x05,0x00,0x38,0x10, - 0x07,0x06,0x3c,0x10,0x04,0x0f,0x12,0x0a,0x03,0x00,0x58,0x0f,0x28,0x80,0x07,0x05, - 0x14,0x00,0x58,0x0f,0x26,0x80,0x36,0x0f,0x05,0x00,0x36,0x10,0x05,0x00,0x38,0x10, - 0x04,0x10,0x20,0x10,0x09,0x10,0x3c,0x10,0x04,0x0f,0x29,0x0f,0x00,0x00,0x01,0x0f, - 0x09,0x00,0x58,0x0f,0x04,0x80,0x36,0x0f,0x05,0x00,0x38,0x0f,0x04,0x0f,0x00,0x08, - 0x0f,0x00,0x58,0x0f,0x1a,0x80,0x29,0x0f,0x00,0x00,0x01,0x09,0x0f,0x00,0x58,0x0f, - 0x05,0x80,0x36,0x0f,0x05,0x00,0x38,0x0f,0x04,0x0f,0x01,0x0f,0x08,0x00,0x58,0x0f, - 0x01,0x80,0x58,0x0f,0x12,0x80,0x12,0x0a,0x03,0x00,0x58,0x0f,0x10,0x80,0x07,0x0d, - 0x16,0x00,0x58,0x0f,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x04,0x80,0x36,0x0f, - 0x09,0x00,0x12,0x11,0x0c,0x00,0x44,0x0f,0x02,0x00,0x58,0x0f,0x08,0x80,0x0f,0x00, - 0x01,0x00,0x58,0x0f,0x06,0x80,0x36,0x0f,0x17,0x00,0x2b,0x11,0x01,0x00,0x27,0x12, - 0x18,0x00,0x12,0x13,0x0d,0x00,0x26,0x12,0x13,0x12,0x42,0x0f,0x03,0x01,0x16,0x0a, - 0x00,0x0a,0x58,0x0b,0x2f,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f,0x6d,0x6d,0x61, - 0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x0b,0x61, - 0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09,0x6c,0x6f,0x6f, - 0x70,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x09,0x65,0x61,0x63, - 0x68,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c, - 0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10, - 0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x73,0x6b,0x69,0x70, - 0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72, - 0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72,0x73, - 0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79, - 0x70,0x65,0x0b,0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00, - 0x0f,0x01,0x7b,0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a, - 0x01,0x01,0x00,0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b, - 0x05,0x01,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29, - 0x09,0x01,0x00,0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58, - 0x06,0x07,0x80,0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12, - 0x08,0x02,0x00,0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b, - 0x01,0x00,0x00,0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58, - 0x06,0x3b,0x80,0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58, - 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, - 0x06,0x33,0x80,0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58, - 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, - 0x06,0x2b,0x80,0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58, - 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, - 0x06,0x23,0x80,0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58, - 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, - 0x06,0x1b,0x80,0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58, - 0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58, - 0x06,0x13,0x80,0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39, - 0x06,0x08,0x06,0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b, - 0x06,0x00,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b, - 0x05,0x02,0x00,0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27, - 0x09,0x0a,0x00,0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f, - 0x00,0x04,0x00,0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29, - 0x07,0x03,0x00,0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36, - 0x06,0x0b,0x00,0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15, - 0x0c,0x00,0x00,0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58, - 0x07,0x05,0x80,0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c, - 0x07,0x02,0x00,0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c, - 0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58, - 0x07,0x06,0x80,0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12, - 0x0b,0x02,0x00,0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07, - 0x6f,0x72,0x08,0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76, - 0x61,0x6c,0x19,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20, - 0x6b,0x6e,0x6f,0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d, - 0x61,0x74,0x63,0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d, - 0x06,0x21,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80, - 0xc0,0x99,0x04,0xd3,0x04,0x03,0x00,0x03,0x00,0x45,0x00,0x49,0x34,0x00,0x00,0x00, - 0x37,0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00, - 0x33,0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00, - 0x33,0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00, - 0x33,0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00, - 0x33,0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00, - 0x33,0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00, - 0x33,0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00, - 0x33,0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00, - 0x33,0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00, - 0x33,0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00, - 0x33,0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00, - 0x33,0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00, - 0x33,0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00, - 0x33,0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00, - 0x33,0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00, - 0x33,0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x37,0x00,0x3e,0x00,0x33,0x00,0x3f,0x00, - 0x37,0x00,0x40,0x00,0x33,0x00,0x41,0x00,0x37,0x00,0x42,0x00,0x36,0x00,0x43,0x00, - 0x39,0x00,0x44,0x00,0x36,0x02,0x40,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00, - 0x0d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x09,0x65,0x76, - 0x61,0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x00,0x0b,0x61,0x63,0x74, - 0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d, - 0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f, - 0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72, - 0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c, - 0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73,0x75,0x62,0x73,0x74, - 0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x00,0x09,0x73,0x71,0x72,0x74,0x00, - 0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64,0x69,0x76,0x00,0x08, - 0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64,0x64,0x00,0x0b,0x72, - 0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73, - 0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08, - 0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e, - 0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a, - 0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64, - 0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01, - 0x00,0x05,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a, - 0x73,0x74,0x6f,0x72,0x65,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02,0x08,0x73, - 0x65,0x74,0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69, - 0x6f,0x6e,0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75, - 0x61,0x67,0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63, - 0x74,0x69,0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a, - 0x22,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d, - 0x65,0x6e,0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22, - 0x63,0x61,0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d, + 0x74,0x43,0x00,0x03,0x07,0x00,0x02,0x00,0x0a,0x0f,0x00,0x02,0x00,0x58,0x03,0x05, + 0x80,0x36,0x03,0x00,0x00,0x12,0x05,0x01,0x00,0x12,0x06,0x02,0x00,0x42,0x03,0x03, + 0x02,0x12,0x01,0x03,0x00,0x36,0x03,0x01,0x00,0x3c,0x01,0x00,0x03,0x4b,0x00,0x01, + 0x00,0x09,0x76,0x61,0x72,0x73,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62, + 0x69,0x67,0x6e,0x75,0x6d,0x2c,0x00,0x01,0x03,0x00,0x02,0x00,0x05,0x36,0x01,0x00, + 0x00,0x36,0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x3c,0x02,0x00,0x01,0x4b,0x00,0x01, + 0x00,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61, + 0x72,0x73,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x38,0x02,0x01,0x00,0x4c,0x02, + 0x02,0x00,0x0f,0x00,0x03,0x03,0x00,0x00,0x00,0x02,0x3c,0x02,0x01,0x00,0x4b,0x00, + 0x01,0x00,0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00, + 0x01,0x00,0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x69, + 0x6e,0x73,0x65,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65,0x28,0x02,0x00,0x03,0x00, + 0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x41, + 0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74, + 0x61,0x62,0x6c,0x65,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x20,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x21,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x22,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x23,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x25,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x24,0x02,0x01,0x00, + 0x4c,0x02,0x02,0x00,0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00, + 0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x09,0x73,0x71,0x72, + 0x74,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x25,0x02,0x00,0x03,0x00,0x02,0x00,0x04, + 0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00, + 0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x02, + 0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02, + 0x00,0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e, + 0x67,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01, + 0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00, + 0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x09,0x67, + 0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25,0x00,0x01,0x04,0x00,0x02, + 0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01, + 0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d, + 0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00, + 0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x1c,0x00,0x01, + 0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02, + 0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x00,0x01,0x04,0x00,0x02, + 0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01, + 0x02,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x23,0x00, + 0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03, + 0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73, + 0x6f,0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36,0x00,0x00,0x00,0x36,0x02, + 0x01,0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27,0x03,0x02,0x00,0x36,0x04, + 0x03,0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47,0x07,0x00,0x00,0x3f,0x07, + 0x00,0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42,0x00,0x03,0x01,0x4b,0x00, + 0x01,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x17,0x61, + 0x73,0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64,0x3a, + 0x20,0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x03,0x80,0x80, + 0xc0,0x99,0x04,0x8e,0x02,0x00,0x01,0x09,0x00,0x08,0x00,0x36,0x36,0x01,0x00,0x00, + 0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07,0x01,0x01,0x00,0x58,0x01,0x21,0x80, + 0x15,0x01,0x00,0x00,0x29,0x02,0x03,0x00,0x03,0x02,0x01,0x00,0x58,0x01,0x2c,0x80, + 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x01,0x00, + 0x29,0x05,0x01,0x00,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x24,0x80, + 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0xff,0xff, + 0x29,0x05,0xff,0xff,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x1c,0x80, + 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x02,0x00, + 0x29,0x05,0xfe,0xff,0x42,0x01,0x04,0x02,0x36,0x02,0x04,0x00,0x38,0x02,0x01,0x02, + 0x0a,0x02,0x00,0x00,0x58,0x02,0x12,0x80,0x36,0x02,0x04,0x00,0x38,0x00,0x01,0x02, + 0x58,0x01,0x0f,0x80,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02, + 0x07,0x01,0x05,0x00,0x58,0x01,0x0a,0x80,0x36,0x01,0x06,0x00,0x12,0x03,0x00,0x00, + 0x42,0x01,0x02,0x04,0x48,0x04,0x04,0x80,0x36,0x06,0x07,0x00,0x12,0x08,0x05,0x00, + 0x42,0x06,0x02,0x02,0x3c,0x06,0x04,0x00,0x46,0x04,0x03,0x03,0x52,0x04,0xfa,0x7f, + 0x4c,0x00,0x02,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67, + 0x0a,0x70,0x61,0x69,0x72,0x73,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72, + 0x73,0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74, + 0x79,0x70,0x65,0xe2,0x06,0x00,0x01,0x15,0x00,0x16,0x01,0xb0,0x01,0x2b,0x01,0x02, + 0x00,0x2b,0x02,0x01,0x00,0x2c,0x03,0x09,0x00,0x29,0x0a,0x01,0x00,0x15,0x0b,0x00, + 0x00,0x03,0x0a,0x0b,0x00,0x58,0x0b,0xa8,0x80,0x55,0x0b,0xa7,0x80,0x38,0x0b,0x0a, + 0x00,0x34,0x0c,0x00,0x00,0x36,0x0d,0x00,0x00,0x12,0x0f,0x0b,0x00,0x42,0x0d,0x02, + 0x04,0x58,0x10,0x08,0x80,0x09,0x10,0x00,0x00,0x58,0x12,0x02,0x80,0x3c,0x11,0x10, + 0x0c,0x58,0x12,0x04,0x80,0x36,0x12,0x01,0x00,0x12,0x14,0x11,0x00,0x42,0x12,0x02, + 0x02,0x3c,0x12,0x10,0x0c,0x45,0x10,0x03,0x03,0x52,0x10,0xf6,0x7f,0x36,0x0d,0x02, + 0x00,0x39,0x0d,0x03,0x0d,0x12,0x0f,0x0c,0x00,0x29,0x10,0x01,0x00,0x42,0x0d,0x03, + 0x02,0x36,0x0e,0x04,0x00,0x38,0x0e,0x0d,0x0e,0x0f,0x00,0x0e,0x00,0x58,0x0f,0x0e, + 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x0f,0x0e,0x00,0x36,0x11,0x05, + 0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x36,0x10,0x06, + 0x00,0x38,0x10,0x0d,0x10,0x0e,0x00,0x10,0x00,0x58,0x10,0x81,0x80,0x36,0x10,0x07, + 0x00,0x3d,0x0f,0x08,0x10,0x58,0x0f,0x7e,0x80,0x07,0x0d,0x09,0x00,0x58,0x0f,0x08, + 0x80,0x36,0x0f,0x0a,0x00,0x36,0x11,0x05,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02, + 0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02,0x01,0x00,0x58,0x0f,0x74, + 0x80,0x07,0x0d,0x0b,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x02, + 0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x6e,0x80,0x0e,0x00,0x02,0x00,0x58,0x0f,0x6c, + 0x80,0x36,0x0f,0x0a,0x00,0x36,0x11,0x05,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02, + 0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02,0x01,0x00,0x58,0x0f,0x64, + 0x80,0x07,0x0d,0x0c,0x00,0x58,0x0f,0x08,0x80,0x0e,0x00,0x01,0x00,0x58,0x0f,0x02, + 0x80,0x13,0x01,0x02,0x00,0x58,0x0f,0x5e,0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x01, + 0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x5a,0x80,0x07,0x0d,0x0d,0x00,0x58,0x0f,0x02, + 0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x56,0x80,0x07,0x0d,0x0e,0x00,0x58,0x0f,0x0b, + 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x09,0x80,0x12,0x03,0x0a,0x00,0x27,0x05,0x0f, + 0x00,0x3a,0x04,0x01,0x0c,0x3a,0x06,0x02,0x0c,0x29,0x07,0x01,0x00,0x36,0x0f,0x07, + 0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04,0x0f,0x58,0x0f,0x49,0x80,0x07,0x0d,0x10, + 0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x03,0x0a, + 0x00,0x27,0x05,0x11,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x08,0x03,0x0c,0x3a,0x0f,0x04, + 0x0c,0x0c,0x09,0x0f,0x00,0x58,0x10,0x01,0x80,0x29,0x09,0x01,0x00,0x36,0x0f,0x07, + 0x00,0x3a,0x10,0x02,0x0c,0x3c,0x10,0x04,0x0f,0x58,0x0f,0x39,0x80,0x07,0x0d,0x12, + 0x00,0x58,0x0f,0x27,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x25,0x80,0x07,0x05,0x0f, + 0x00,0x58,0x0f,0x09,0x80,0x16,0x07,0x00,0x07,0x15,0x0f,0x06,0x00,0x03,0x07,0x0f, + 0x00,0x58,0x0f,0x2f,0x80,0x36,0x0f,0x07,0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04, + 0x0f,0x12,0x0a,0x03,0x00,0x58,0x0f,0x2a,0x80,0x07,0x05,0x11,0x00,0x58,0x0f,0x16, + 0x80,0x36,0x0f,0x07,0x00,0x36,0x10,0x07,0x00,0x38,0x10,0x04,0x10,0x20,0x10,0x09, + 0x10,0x3c,0x10,0x04,0x0f,0x29,0x0f,0x00,0x00,0x01,0x0f,0x09,0x00,0x58,0x0f,0x04, + 0x80,0x36,0x0f,0x07,0x00,0x38,0x0f,0x04,0x0f,0x00,0x08,0x0f,0x00,0x58,0x0f,0x1c, + 0x80,0x29,0x0f,0x00,0x00,0x01,0x09,0x0f,0x00,0x58,0x0f,0x05,0x80,0x36,0x0f,0x07, + 0x00,0x38,0x0f,0x04,0x0f,0x01,0x0f,0x08,0x00,0x58,0x0f,0x01,0x80,0x58,0x0f,0x14, + 0x80,0x12,0x0a,0x03,0x00,0x58,0x0f,0x12,0x80,0x29,0x0a,0x00,0x00,0x58,0x0f,0x10, + 0x80,0x07,0x0d,0x13,0x00,0x58,0x0f,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x04, + 0x80,0x36,0x0f,0x05,0x00,0x12,0x11,0x0c,0x00,0x44,0x0f,0x02,0x00,0x58,0x0f,0x08, + 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x06,0x80,0x36,0x0f,0x14,0x00,0x2b,0x11,0x01, + 0x00,0x27,0x12,0x15,0x00,0x12,0x13,0x0d,0x00,0x26,0x12,0x13,0x12,0x42,0x0f,0x03, + 0x01,0x16,0x0a,0x00,0x0a,0x58,0x0b,0x55,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f, + 0x6d,0x6d,0x61,0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a, + 0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09, + 0x6c,0x6f,0x6f,0x70,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x09, + 0x65,0x61,0x63,0x68,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64, + 0x09,0x65,0x6c,0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07, + 0x69,0x66,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76, + 0x61,0x72,0x73,0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b, + 0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61, + 0x62,0x6c,0x65,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0b, + 0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00,0x0f,0x01,0x7b, + 0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a,0x01,0x01,0x00, + 0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b,0x05,0x01,0x00, + 0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x01,0x00, + 0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58,0x06,0x07,0x80, + 0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00, + 0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b,0x01,0x00,0x00, + 0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58,0x06,0x3b,0x80, + 0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58,0x06,0x02,0x80, + 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x33,0x80, + 0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58,0x06,0x02,0x80, + 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x2b,0x80, + 0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58,0x06,0x02,0x80, + 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x23,0x80, + 0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58,0x06,0x02,0x80, + 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x1b,0x80, + 0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58,0x06,0x02,0x80, + 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x13,0x80, + 0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39,0x06,0x08,0x06, + 0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b,0x06,0x00,0x00, + 0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00, + 0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27,0x09,0x0a,0x00, + 0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f,0x00,0x04,0x00, + 0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29,0x07,0x03,0x00, + 0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36,0x06,0x0b,0x00, + 0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15,0x0c,0x00,0x00, + 0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58,0x07,0x05,0x80, + 0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00, + 0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c,0x07,0x05,0x00, + 0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x06,0x80, + 0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12,0x0b,0x02,0x00, + 0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07,0x6f,0x72,0x08, + 0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76,0x61,0x6c,0x19, + 0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20,0x6b,0x6e,0x6f, + 0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d,0x61,0x74,0x63, + 0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d,0x06,0x21,0x08, + 0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80,0xc0,0x99,0x04, + 0xab,0x05,0x00,0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02,0x00,0x00,0x12,0x04,0x00, + 0x00,0x42,0x02,0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02,0x04,0x80,0x36,0x02,0x02, + 0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00,0x02,0x00,0x36,0x02,0x03, + 0x00,0x36,0x04,0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06,0x00,0x00,0x27,0x07,0x05, + 0x00,0x42,0x04,0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04,0x02,0x80,0x2b,0x04,0x01, + 0x00,0x58,0x05,0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05,0x06,0x00,0x42,0x02,0x03, + 0x01,0x36,0x02,0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04,0x00,0x00,0x27,0x05,0x08, + 0x00,0x27,0x06,0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04,0x03,0x00,0x29,0x06,0x01, + 0x00,0x02,0x03,0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06,0x01,0x00,0x58,0x07,0x01, + 0x80,0x2b,0x06,0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04,0x03,0x01,0x09,0x03,0x00, + 0x00,0x58,0x04,0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07,0x01,0x00,0x39,0x05,0x0b, + 0x01,0x42,0x05,0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05,0x02,0x80,0x29,0x04,0x12, + 0x00,0x58,0x05,0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05,0x0e,0x05,0x12,0x07,0x01, + 0x00,0x27,0x08,0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04,0x05,0x00,0x36,0x05,0x03, + 0x00,0x29,0x07,0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07,0x03,0x80,0x29,0x07,0x12, + 0x00,0x02,0x04,0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07,0x01,0x00,0x58,0x08,0x01, + 0x80,0x2b,0x07,0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05,0x03,0x01,0x36,0x05,0x01, + 0x00,0x39,0x05,0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08,0x00,0x00,0x27,0x09,0x11, + 0x00,0x26,0x07,0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05,0x03,0x03,0x15,0x07,0x06, + 0x00,0x21,0x07,0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08,0x07,0x00,0x58,0x08,0x08, + 0x80,0x12,0x08,0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09,0x13,0x09,0x27,0x0b,0x11, + 0x00,0x12,0x0c,0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06,0x09,0x08,0x58,0x08,0x0a, + 0x80,0x29,0x08,0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08,0x07,0x80,0x36,0x08,0x01, + 0x00,0x39,0x08,0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b,0x01,0x00,0x12,0x0c,0x04, + 0x00,0x42,0x08,0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08,0x05,0x00,0x12,0x09,0x06, + 0x00,0x26,0x00,0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08,0x07,0x08,0x12,0x0a,0x00, + 0x00,0x27,0x0b,0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d,0x01,0x00,0x42,0x08,0x05, + 0x02,0x12,0x00,0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08,0x01,0x00,0x58,0x08,0x01, + 0x80,0x27,0x00,0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04,0x17,0x04,0x12,0x06,0x00, + 0x00,0x44,0x04,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67, + 0x6e,0x75,0x6d,0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08,0x72,0x65,0x70,0x11,0x28, + 0x25,0x64,0x2b,0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29,0x06,0x30,0x20,0x74,0x6f, + 0x6b,0x65,0x6e,0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64, + 0x20,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64,0x65,0x63,0x69,0x6d,0x61, + 0x6c,0x73,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, + 0x0a,0x61,0x65,0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65,0x72,0x1a,0x74,0x68,0x65, + 0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c, + 0x69,0x64,0x05,0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62,0x2a,0x74,0x68,0x65,0x20, + 0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x20, + 0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65, + 0x72,0x0c,0x5b,0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b, + 0x61,0x73,0x73,0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x0b, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65,0x02,0x00,0x86,0x05,0x03, + 0x00,0x03,0x00,0x49,0x00,0x4d,0x34,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x35,0x00, + 0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33,0x01,0x03,0x00,0x3d,0x01, + 0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33,0x01,0x08,0x00,0x3d,0x01, + 0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33,0x01,0x0c,0x00,0x3d,0x01, + 0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33,0x01,0x10,0x00,0x3d,0x01, + 0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33,0x01,0x14,0x00,0x3d,0x01, + 0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33,0x01,0x18,0x00,0x3d,0x01, + 0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33,0x01,0x1c,0x00,0x3d,0x01, + 0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33,0x01,0x20,0x00,0x3d,0x01, + 0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33,0x01,0x24,0x00,0x3d,0x01, + 0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33,0x01,0x28,0x00,0x3d,0x01, + 0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33,0x01,0x2c,0x00,0x3d,0x01, + 0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33,0x01,0x30,0x00,0x3d,0x01, + 0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33,0x01,0x34,0x00,0x3d,0x01, + 0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33,0x01,0x38,0x00,0x3d,0x01, + 0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33,0x01,0x3c,0x00,0x3d,0x01, + 0x3d,0x00,0x37,0x00,0x3e,0x00,0x33,0x00,0x3f,0x00,0x37,0x00,0x40,0x00,0x33,0x00, + 0x41,0x00,0x37,0x00,0x42,0x00,0x33,0x00,0x43,0x00,0x37,0x00,0x44,0x00,0x33,0x00, + 0x45,0x00,0x37,0x00,0x46,0x00,0x36,0x00,0x47,0x00,0x39,0x00,0x48,0x00,0x36,0x02, + 0x42,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d,0x72,0x65,0x67,0x69,0x73, + 0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f, + 0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61,0x6c,0x00,0x0c,0x65,0x78, + 0x65,0x63,0x75,0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61, + 0x72,0x67,0x00,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72, + 0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a, + 0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74, + 0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75, + 0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64, + 0x00,0x0b,0x73,0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74, + 0x00,0x09,0x73,0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77, + 0x00,0x08,0x64,0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00, + 0x08,0x61,0x64,0x64,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e, + 0x73,0x65,0x72,0x74,0x00,0x08,0x73,0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a, + 0x73,0x74,0x6f,0x72,0x65,0x00,0x08,0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64, + 0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c, + 0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61, + 0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00, + 0x00,0x09,0x73,0x6b,0x69,0x70,0x01,0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74, + 0x02,0x08,0x6c,0x65,0x74,0x02,0x0a,0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73,0x65, + 0x6e,0x64,0x02,0x08,0x73,0x65,0x74,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02, + 0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22, + 0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67,0x65, + 0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, + 0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65,0x78, + 0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74, + 0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61,0x6c, + 0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d, } diff --git a/contract/vm_multicall.lua b/contract/vm_multicall.lua index e0ec420f2..6997917ef 100644 --- a/contract/vm_multicall.lua +++ b/contract/vm_multicall.lua @@ -4,7 +4,7 @@ vars = {} -skip = {store=true,let=true,set=true,insert=true,assert=true} +skip = {store=true,let=true,set=true,insert=true,assert=true,send=true} action = { @@ -19,14 +19,14 @@ action = { send = function (address,amount) return contract.send(address, amount) end, -- variables - let = function (x,y) vars[x] = y end, + let = function (x,y,z) if z then y = convert_bignum(y,z) end vars[x] = y end, store = function (n) vars[n] = vars['last_result'] end, -- tables get = function (o,k) return o[k] end, set = function (o,k,v) o[k] = v end, insert = function (...) table.insert(...) end, -- inserts at the end if no pos informed - remove = function (...) table.remove(...) end, + remove = function (...) table.remove(...) end, -- returns the removed item -- math add = function (x,y) return x+y end, @@ -55,6 +55,20 @@ action = { } +function process_arg(arg) + if type(arg) == 'string' then + if #arg >= 3 and string.sub(arg, 1, 1) == '%' and string.sub(arg, -1, -1) == '%' then + local varname = string.sub(arg, 2, -2) + if vars[varname] ~= nil then + arg = vars[varname] + end + end + elseif type(arg) == 'table' then + for k,v in pairs(arg) do arg[k] = process_arg(v) end + end + return arg +end + function execute(calls) local if_on = true @@ -69,16 +83,13 @@ function execute(calls) while cmdpos <= #calls do local call = calls[cmdpos] local args = {} -- use a copy of the list because of loops - for i,v in ipairs(call) do args[i] = v end - - -- process variables - for i,item in ipairs(args) do - if i > 1 and type(item) == 'string' and #item >= 3 and - string.sub(item, 1, 1) == '%' and string.sub(item, -1, -1) == '%' then - local varname = string.sub(item, 2, -2) - if vars[varname] ~= nil then - args[i] = vars[varname] - end + + -- copy values and process variables + for i,arg in ipairs(call) do + if i == 1 then + args[i] = arg + else + args[i] = process_arg(arg) end end @@ -136,6 +147,8 @@ function execute(calls) else cmdpos = for_cmdpos end + else + cmdpos = 0 end -- return @@ -193,4 +206,33 @@ function eval(...) return matches end +function convert_bignum(x, token) + if type(x) ~= 'string' then + x = tostring(x) + end + assert(string.match(x, '[^0-9.]') == nil, "the amount contains invalid character") + local _, count = string.gsub(x, "%.", "") + assert(count <= 1, "the amount is invalid") + if count == 1 then + local num_decimals + if token:lower() == 'aergo' then + num_decimals = 18 + else + num_decimals = contract.call(token, "decimals") + end + assert(num_decimals >= 0 and num_decimals <= 18, "token with invalid decimals") + local p1, p2 = string.match('0' .. x .. '0', '(%d+)%.(%d+)') + local to_add = num_decimals - #p2 + if to_add > 0 then + p2 = p2 .. string.rep('0', to_add) + elseif to_add < 0 then + p2 = string.sub(p2, 1, num_decimals) + end + x = p1 .. p2 + x = string.gsub(x, '0*', '', 1) -- remove leading zeros + if #x == 0 then x = '0' end + end + return bignum.number(x) +end + abi.register(execute) From e973975c2435cc93f289bb9d5138b1e7939036be Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Tue, 26 Jul 2022 22:26:25 -0300 Subject: [PATCH 06/49] [contract] add functions to composable transactions --- contract/vm_multicall.go | 539 ++++++++++++++++++++------------------ contract/vm_multicall.lua | 54 +++- 2 files changed, 330 insertions(+), 263 deletions(-) diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go index 0c96e4973..fe9864826 100644 --- a/contract/vm_multicall.go +++ b/contract/vm_multicall.go @@ -1,7 +1,7 @@ package contract var multicall_payload = []byte { - 0x51,0x10,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, + 0x62,0x12,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, 0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00, 0x00,0x00,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, 0x37,0x02,0x01,0x04,0x00,0x03,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, @@ -16,257 +16,290 @@ var multicall_payload = []byte { 0x02,0x04,0x39,0x04,0x03,0x04,0x12,0x06,0x00,0x00,0x42,0x04,0x02,0x02,0x47,0x05, 0x01,0x00,0x41,0x02,0x01,0x00,0x3f,0x02,0x00,0x00,0x4c,0x01,0x02,0x00,0x0a,0x76, 0x61,0x6c,0x75,0x65,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61, - 0x63,0x74,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x28,0x00, - 0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03, - 0x00,0x00,0x44,0x01,0x02,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x0d,0x63, - 0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x29,0x00,0x02,0x06,0x00,0x02,0x00,0x05,0x36, - 0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x12,0x04,0x00,0x00,0x12,0x05,0x01,0x00,0x44, - 0x02,0x03,0x00,0x09,0x73,0x65,0x6e,0x64,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63, - 0x74,0x43,0x00,0x03,0x07,0x00,0x02,0x00,0x0a,0x0f,0x00,0x02,0x00,0x58,0x03,0x05, - 0x80,0x36,0x03,0x00,0x00,0x12,0x05,0x01,0x00,0x12,0x06,0x02,0x00,0x42,0x03,0x03, - 0x02,0x12,0x01,0x03,0x00,0x36,0x03,0x01,0x00,0x3c,0x01,0x00,0x03,0x4b,0x00,0x01, - 0x00,0x09,0x76,0x61,0x72,0x73,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62, - 0x69,0x67,0x6e,0x75,0x6d,0x2c,0x00,0x01,0x03,0x00,0x02,0x00,0x05,0x36,0x01,0x00, - 0x00,0x36,0x02,0x00,0x00,0x39,0x02,0x01,0x02,0x3c,0x02,0x00,0x01,0x4b,0x00,0x01, - 0x00,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61, - 0x72,0x73,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x38,0x02,0x01,0x00,0x4c,0x02, - 0x02,0x00,0x0f,0x00,0x03,0x03,0x00,0x00,0x00,0x02,0x3c,0x02,0x01,0x00,0x4b,0x00, - 0x01,0x00,0x28,0x02,0x00,0x03,0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00, - 0x01,0x00,0x47,0x02,0x00,0x00,0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x69, - 0x6e,0x73,0x65,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65,0x28,0x02,0x00,0x03,0x00, - 0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x41, - 0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74, - 0x61,0x62,0x6c,0x65,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x20,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x21,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x22,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x23,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x25,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x24,0x02,0x01,0x00, - 0x4c,0x02,0x02,0x00,0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00, - 0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x09,0x73,0x71,0x72, - 0x74,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x25,0x02,0x00,0x03,0x00,0x02,0x00,0x04, - 0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00, - 0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x02, - 0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02, - 0x00,0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e, - 0x67,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01, - 0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b, - 0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00, - 0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x09,0x67, - 0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25,0x00,0x01,0x04,0x00,0x02, - 0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01, + 0x63,0x74,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x42,0x00, + 0x01,0x06,0x00,0x04,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x36,0x03, + 0x02,0x00,0x39,0x03,0x03,0x03,0x12,0x05,0x00,0x00,0x42,0x03,0x02,0x00,0x43,0x01, + 0x00,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x0d,0x63,0x6f,0x6e,0x74,0x72, + 0x61,0x63,0x74,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75, + 0x6d,0x29,0x00,0x02,0x06,0x00,0x02,0x00,0x05,0x36,0x02,0x00,0x00,0x39,0x02,0x01, + 0x02,0x12,0x04,0x00,0x00,0x12,0x05,0x01,0x00,0x44,0x02,0x03,0x00,0x09,0x73,0x65, + 0x6e,0x64,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x43,0x00,0x03,0x07,0x00, + 0x02,0x00,0x0a,0x0f,0x00,0x02,0x00,0x58,0x03,0x05,0x80,0x36,0x03,0x00,0x00,0x12, + 0x05,0x01,0x00,0x12,0x06,0x02,0x00,0x42,0x03,0x03,0x02,0x12,0x01,0x03,0x00,0x36, + 0x03,0x01,0x00,0x3c,0x01,0x00,0x03,0x4b,0x00,0x01,0x00,0x09,0x76,0x61,0x72,0x73, + 0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x2c, + 0x00,0x01,0x03,0x00,0x02,0x00,0x05,0x36,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x39, + 0x02,0x01,0x02,0x3c,0x02,0x00,0x01,0x4b,0x00,0x01,0x00,0x10,0x6c,0x61,0x73,0x74, + 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x0f,0x00,0x02,0x03, + 0x00,0x00,0x00,0x02,0x38,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x03,0x03, + 0x00,0x00,0x00,0x02,0x3c,0x02,0x01,0x00,0x4b,0x00,0x01,0x00,0x28,0x02,0x00,0x03, + 0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00, + 0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x0a, + 0x74,0x61,0x62,0x6c,0x65,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00, + 0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0b,0x72,0x65, + 0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0f,0x00,0x01,0x02,0x00,0x00, + 0x00,0x02,0x15,0x01,0x00,0x00,0x4c,0x01,0x02,0x00,0x55,0x00,0x01,0x09,0x00,0x03, + 0x01,0x0f,0x34,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02, + 0x02,0x04,0x48,0x05,0x03,0x80,0x15,0x07,0x01,0x00,0x16,0x07,0x00,0x07,0x3c,0x05, + 0x07,0x01,0x46,0x05,0x03,0x03,0x52,0x05,0xfb,0x7f,0x36,0x02,0x01,0x00,0x39,0x02, + 0x02,0x02,0x12,0x04,0x01,0x00,0x42,0x02,0x02,0x01,0x4c,0x01,0x02,0x00,0x09,0x73, + 0x6f,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0a,0x70,0x61,0x69,0x72,0x73,0x02, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x20,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x21,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x22,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x23,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x25,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x24,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, + 0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, + 0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x09,0x73,0x71,0x72,0x74,0x0b,0x62,0x69, + 0x67,0x6e,0x75,0x6d,0x32,0x02,0x00,0x04,0x00,0x02,0x01,0x06,0x36,0x00,0x00,0x00, + 0x39,0x00,0x01,0x00,0x34,0x02,0x03,0x00,0x47,0x03,0x00,0x00,0x3f,0x03,0x00,0x00, + 0x44,0x00,0x02,0x00,0x0b,0x63,0x6f,0x6e,0x63,0x61,0x74,0x0a,0x74,0x61,0x62,0x6c, + 0x65,0x03,0x80,0x80,0xc0,0x99,0x04,0x25,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36, + 0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0b, + 0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x02,0x00, + 0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00, + 0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67, + 0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00, + 0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b,0x73, + 0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00, + 0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x09,0x67,0x73, + 0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25,0x00,0x01,0x04,0x00,0x02,0x00, + 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, + 0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x1c, + 0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44, + 0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x1c,0x00,0x01,0x04, + 0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00, + 0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x00,0x01,0x04,0x00,0x02,0x00, + 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, + 0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x23,0x00,0x01, + 0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00, + 0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f, + 0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36,0x00,0x00,0x00,0x36,0x02,0x01, + 0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27,0x03,0x02,0x00,0x36,0x04,0x03, + 0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47,0x07,0x00,0x00,0x3f,0x07,0x00, + 0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42,0x00,0x03,0x01,0x4b,0x00,0x01, + 0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x17,0x61,0x73, + 0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64,0x3a,0x20, + 0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x03,0x80,0x80,0xc0, + 0x99,0x04,0x8e,0x02,0x00,0x01,0x09,0x00,0x08,0x00,0x36,0x36,0x01,0x00,0x00,0x12, + 0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07,0x01,0x01,0x00,0x58,0x01,0x21,0x80,0x15, + 0x01,0x00,0x00,0x29,0x02,0x03,0x00,0x03,0x02,0x01,0x00,0x58,0x01,0x2c,0x80,0x36, + 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x01,0x00,0x29, + 0x05,0x01,0x00,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x24,0x80,0x36, + 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0xff,0xff,0x29, + 0x05,0xff,0xff,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x1c,0x80,0x36, + 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x02,0x00,0x29, + 0x05,0xfe,0xff,0x42,0x01,0x04,0x02,0x36,0x02,0x04,0x00,0x38,0x02,0x01,0x02,0x0a, + 0x02,0x00,0x00,0x58,0x02,0x12,0x80,0x36,0x02,0x04,0x00,0x38,0x00,0x01,0x02,0x58, + 0x01,0x0f,0x80,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07, + 0x01,0x05,0x00,0x58,0x01,0x0a,0x80,0x36,0x01,0x06,0x00,0x12,0x03,0x00,0x00,0x42, + 0x01,0x02,0x04,0x48,0x04,0x04,0x80,0x36,0x06,0x07,0x00,0x12,0x08,0x05,0x00,0x42, + 0x06,0x02,0x02,0x3c,0x06,0x04,0x00,0x46,0x04,0x03,0x03,0x52,0x04,0xfa,0x7f,0x4c, + 0x00,0x02,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0a, + 0x70,0x61,0x69,0x72,0x73,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72,0x73, + 0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79, + 0x70,0x65,0x90,0x09,0x00,0x01,0x18,0x00,0x1a,0x01,0xf5,0x01,0x2b,0x01,0x02,0x00, + 0x2b,0x02,0x01,0x00,0x2c,0x03,0x0b,0x00,0x2b,0x0c,0x01,0x00,0x29,0x0d,0x01,0x00, + 0x15,0x0e,0x00,0x00,0x03,0x0d,0x0e,0x00,0x58,0x0e,0xec,0x80,0x55,0x0e,0xeb,0x80, + 0x38,0x0e,0x0d,0x00,0x34,0x0f,0x00,0x00,0x36,0x10,0x00,0x00,0x12,0x12,0x0e,0x00, + 0x42,0x10,0x02,0x04,0x58,0x13,0x08,0x80,0x09,0x13,0x00,0x00,0x58,0x15,0x02,0x80, + 0x3c,0x14,0x13,0x0f,0x58,0x15,0x04,0x80,0x36,0x15,0x01,0x00,0x12,0x17,0x14,0x00, + 0x42,0x15,0x02,0x02,0x3c,0x15,0x13,0x0f,0x45,0x13,0x03,0x03,0x52,0x13,0xf6,0x7f, + 0x36,0x10,0x02,0x00,0x39,0x10,0x03,0x10,0x12,0x12,0x0f,0x00,0x29,0x13,0x01,0x00, + 0x42,0x10,0x03,0x02,0x36,0x11,0x04,0x00,0x38,0x11,0x10,0x11,0x0f,0x00,0x11,0x00, + 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x12,0x12,0x11,0x00, + 0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00,0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02, + 0x36,0x13,0x06,0x00,0x38,0x13,0x10,0x13,0x0e,0x00,0x13,0x00,0x58,0x13,0xa7,0x80, + 0x36,0x13,0x07,0x00,0x3d,0x12,0x08,0x13,0x58,0x12,0xa4,0x80,0x07,0x10,0x09,0x00, + 0x58,0x12,0x08,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, + 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, + 0x58,0x12,0x9a,0x80,0x07,0x10,0x0b,0x00,0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00, + 0x58,0x12,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x12,0x94,0x80,0x0e,0x00,0x02,0x00, + 0x58,0x12,0x92,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, + 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, + 0x58,0x12,0x8a,0x80,0x07,0x10,0x0c,0x00,0x58,0x12,0x08,0x80,0x0e,0x00,0x01,0x00, + 0x58,0x12,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x12,0x84,0x80,0x2b,0x01,0x01,0x00, + 0x58,0x12,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x80,0x80,0x07,0x10,0x0d,0x00, + 0x58,0x12,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x7c,0x80,0x07,0x10,0x0e,0x00, + 0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x04,0x80,0x27,0x05,0x0f,0x00, + 0x34,0x07,0x00,0x00,0x3a,0x08,0x02,0x0f,0x58,0x12,0x74,0x80,0x07,0x10,0x10,0x00, + 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x3a,0x05,0x02,0x0f, + 0x3a,0x07,0x03,0x0f,0x36,0x12,0x04,0x00,0x39,0x12,0x11,0x12,0x12,0x14,0x07,0x00, + 0x42,0x12,0x02,0x02,0x12,0x08,0x12,0x00,0x36,0x12,0x07,0x00,0x3a,0x13,0x01,0x08, + 0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x58,0x12,0x64,0x80,0x07,0x10,0x12,0x00, + 0x58,0x12,0x1f,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x1d,0x80,0x12,0x03,0x0d,0x00, + 0x27,0x06,0x13,0x00,0x3a,0x04,0x01,0x0f,0x3a,0x0a,0x03,0x0f,0x3a,0x12,0x04,0x0f, + 0x0c,0x0b,0x12,0x00,0x58,0x13,0x01,0x80,0x29,0x0b,0x01,0x00,0x36,0x12,0x07,0x00, + 0x3a,0x13,0x02,0x0f,0x3c,0x13,0x04,0x12,0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00, + 0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00, + 0x58,0x12,0x09,0x80,0x29,0x12,0x00,0x00,0x01,0x0b,0x12,0x00,0x58,0x12,0x04,0x80, + 0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x12,0x0a,0x00,0x58,0x12,0x02,0x80, + 0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x43,0x80, + 0x07,0x10,0x14,0x00,0x58,0x12,0x04,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x02,0x80, + 0x2b,0x0c,0x02,0x00,0x58,0x12,0x3d,0x80,0x07,0x10,0x15,0x00,0x58,0x12,0x2b,0x80, + 0x0f,0x00,0x01,0x00,0x58,0x12,0x29,0x80,0x07,0x06,0x16,0x00,0x58,0x12,0x0d,0x80, + 0x16,0x09,0x00,0x09,0x15,0x12,0x08,0x00,0x03,0x09,0x12,0x00,0x58,0x12,0x33,0x80, + 0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08,0x3c,0x13,0x04,0x12,0x36,0x12,0x07,0x00, + 0x38,0x13,0x09,0x08,0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x12,0x0d,0x03,0x00, + 0x58,0x12,0x2a,0x80,0x07,0x06,0x13,0x00,0x58,0x12,0x16,0x80,0x36,0x12,0x07,0x00, + 0x36,0x13,0x07,0x00,0x38,0x13,0x04,0x13,0x20,0x13,0x0b,0x13,0x3c,0x13,0x04,0x12, + 0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00,0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00, + 0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00,0x58,0x12,0x1c,0x80,0x29,0x12,0x00,0x00, + 0x01,0x0b,0x12,0x00,0x58,0x12,0x05,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12, + 0x01,0x12,0x0a,0x00,0x58,0x12,0x01,0x80,0x58,0x12,0x14,0x80,0x12,0x0d,0x03,0x00, + 0x58,0x12,0x12,0x80,0x29,0x0d,0x00,0x00,0x58,0x12,0x10,0x80,0x07,0x10,0x17,0x00, + 0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x04,0x80,0x36,0x12,0x05,0x00, + 0x12,0x14,0x0f,0x00,0x44,0x12,0x02,0x00,0x58,0x12,0x08,0x80,0x0f,0x00,0x01,0x00, + 0x58,0x12,0x06,0x80,0x36,0x12,0x18,0x00,0x2b,0x14,0x01,0x00,0x27,0x15,0x19,0x00, + 0x12,0x16,0x10,0x00,0x26,0x15,0x16,0x15,0x42,0x12,0x03,0x01,0x0f,0x00,0x01,0x00, + 0x58,0x12,0x11,0x80,0x06,0x10,0x0e,0x00,0x58,0x12,0x02,0x80,0x07,0x10,0x10,0x00, + 0x58,0x12,0x0d,0x80,0x12,0x03,0x0d,0x00,0x27,0x06,0x16,0x00,0x3a,0x04,0x01,0x0f, + 0x29,0x09,0x01,0x00,0x36,0x12,0x07,0x00,0x3a,0x13,0x01,0x08,0x3c,0x13,0x04,0x12, + 0x3a,0x12,0x01,0x08,0x0a,0x12,0x00,0x00,0x58,0x12,0x02,0x80,0x2b,0x0c,0x01,0x00, + 0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x0f,0x00,0x0c,0x00,0x58,0x12,0x09,0x80, + 0x55,0x12,0x07,0x80,0x16,0x0d,0x00,0x0d,0x38,0x0e,0x0d,0x00,0x0a,0x0e,0x00,0x00, + 0x58,0x12,0x03,0x80,0x3a,0x12,0x01,0x0e,0x07,0x12,0x15,0x00,0x58,0x12,0xf8,0x7f, + 0x2b,0x0c,0x01,0x00,0x16,0x0d,0x00,0x0d,0x58,0x0e,0x11,0x7f,0x4b,0x00,0x01,0x00, + 0x18,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75, + 0x6e,0x64,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75, + 0x72,0x6e,0x09,0x65,0x61,0x63,0x68,0x09,0x6c,0x6f,0x6f,0x70,0x0a,0x62,0x72,0x65, + 0x61,0x6b,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x0d,0x67,0x65, + 0x74,0x5f,0x6b,0x65,0x79,0x73,0x0c,0x66,0x6f,0x72,0x70,0x61,0x69,0x72,0x07,0x5f, + 0x5f,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c, + 0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10, + 0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73, + 0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74, + 0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65, + 0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0b,0x69,0x70,0x61, + 0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00,0x0f,0x01,0x7b,0x34,0x00,0x03, + 0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a,0x01,0x01,0x00,0x3a,0x02,0x02, + 0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b,0x05,0x01,0x00,0x36,0x06,0x00, + 0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x01,0x00,0x29,0x0a,0x01, + 0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58,0x06,0x07,0x80,0x2b,0x04,0x02, + 0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x02, + 0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b,0x01,0x00,0x00,0x58,0x06,0x03, + 0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58,0x06,0x3b,0x80,0x07,0x02,0x03, + 0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, + 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x33,0x80,0x07,0x02,0x04, + 0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, + 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x2b,0x80,0x07,0x02,0x05, + 0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, + 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x23,0x80,0x07,0x02,0x06, + 0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, + 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x1b,0x80,0x07,0x02,0x07, + 0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, + 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x13,0x80,0x07,0x02,0x08, + 0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39,0x06,0x08,0x06,0x12,0x08,0x01, + 0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b,0x06,0x00,0x00,0x58,0x06,0x02, + 0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x06, + 0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27,0x09,0x0a,0x00,0x12,0x0a,0x02, + 0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f,0x00,0x04,0x00,0x58,0x06,0x01, + 0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29,0x07,0x03,0x00,0x01,0x07,0x06, + 0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36,0x06,0x0b,0x00,0x36,0x08,0x0c, + 0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15,0x0c,0x00,0x00,0x42,0x08,0x04, + 0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58,0x07,0x05,0x80,0x0d,0x07,0x05, + 0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x0d, + 0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c,0x07,0x05,0x00,0x58,0x07,0x01, + 0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x06,0x80,0x36,0x07,0x09, + 0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12,0x0b,0x02,0x00,0x26,0x0a,0x0b, + 0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07,0x6f,0x72,0x08,0x61,0x6e,0x64, + 0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76,0x61,0x6c,0x19,0x6f,0x70,0x65, + 0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20,0x6b,0x6e,0x6f,0x77,0x6e,0x3a, + 0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d,0x61,0x74,0x63,0x68,0x07,0x3c, + 0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d,0x06,0x21,0x08,0x73,0x75,0x62, + 0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80,0xc0,0x99,0x04,0xab,0x05,0x00, + 0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02,0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02, + 0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02,0x04,0x80,0x36,0x02,0x02,0x00,0x12,0x04, + 0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00,0x02,0x00,0x36,0x02,0x03,0x00,0x36,0x04, + 0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06,0x00,0x00,0x27,0x07,0x05,0x00,0x42,0x04, + 0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04,0x02,0x80,0x2b,0x04,0x01,0x00,0x58,0x05, + 0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05,0x06,0x00,0x42,0x02,0x03,0x01,0x36,0x02, + 0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04,0x00,0x00,0x27,0x05,0x08,0x00,0x27,0x06, + 0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04,0x03,0x00,0x29,0x06,0x01,0x00,0x02,0x03, + 0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06,0x01,0x00,0x58,0x07,0x01,0x80,0x2b,0x06, + 0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04,0x03,0x01,0x09,0x03,0x00,0x00,0x58,0x04, + 0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07,0x01,0x00,0x39,0x05,0x0b,0x01,0x42,0x05, + 0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05,0x02,0x80,0x29,0x04,0x12,0x00,0x58,0x05, + 0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05,0x0e,0x05,0x12,0x07,0x01,0x00,0x27,0x08, + 0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04,0x05,0x00,0x36,0x05,0x03,0x00,0x29,0x07, + 0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07,0x03,0x80,0x29,0x07,0x12,0x00,0x02,0x04, + 0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07,0x01,0x00,0x58,0x08,0x01,0x80,0x2b,0x07, + 0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05,0x03,0x01,0x36,0x05,0x01,0x00,0x39,0x05, + 0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08,0x00,0x00,0x27,0x09,0x11,0x00,0x26,0x07, + 0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05,0x03,0x03,0x15,0x07,0x06,0x00,0x21,0x07, + 0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08,0x07,0x00,0x58,0x08,0x08,0x80,0x12,0x08, + 0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09,0x13,0x09,0x27,0x0b,0x11,0x00,0x12,0x0c, + 0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06,0x09,0x08,0x58,0x08,0x0a,0x80,0x29,0x08, + 0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08,0x07,0x80,0x36,0x08,0x01,0x00,0x39,0x08, + 0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b,0x01,0x00,0x12,0x0c,0x04,0x00,0x42,0x08, + 0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08,0x05,0x00,0x12,0x09,0x06,0x00,0x26,0x00, + 0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08,0x07,0x08,0x12,0x0a,0x00,0x00,0x27,0x0b, + 0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d,0x01,0x00,0x42,0x08,0x05,0x02,0x12,0x00, + 0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08,0x01,0x00,0x58,0x08,0x01,0x80,0x27,0x00, + 0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04,0x17,0x04,0x12,0x06,0x00,0x00,0x44,0x04, 0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d, - 0x1c,0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00, - 0x44,0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x1c,0x00,0x01, - 0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02, - 0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x00,0x01,0x04,0x00,0x02, - 0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01, - 0x02,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x23,0x00, - 0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03, - 0x00,0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73, - 0x6f,0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36,0x00,0x00,0x00,0x36,0x02, - 0x01,0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27,0x03,0x02,0x00,0x36,0x04, - 0x03,0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47,0x07,0x00,0x00,0x3f,0x07, - 0x00,0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42,0x00,0x03,0x01,0x4b,0x00, - 0x01,0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x17,0x61, - 0x73,0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64,0x3a, - 0x20,0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x03,0x80,0x80, - 0xc0,0x99,0x04,0x8e,0x02,0x00,0x01,0x09,0x00,0x08,0x00,0x36,0x36,0x01,0x00,0x00, - 0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07,0x01,0x01,0x00,0x58,0x01,0x21,0x80, - 0x15,0x01,0x00,0x00,0x29,0x02,0x03,0x00,0x03,0x02,0x01,0x00,0x58,0x01,0x2c,0x80, - 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x01,0x00, - 0x29,0x05,0x01,0x00,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x24,0x80, - 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0xff,0xff, - 0x29,0x05,0xff,0xff,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x1c,0x80, - 0x36,0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x02,0x00, - 0x29,0x05,0xfe,0xff,0x42,0x01,0x04,0x02,0x36,0x02,0x04,0x00,0x38,0x02,0x01,0x02, - 0x0a,0x02,0x00,0x00,0x58,0x02,0x12,0x80,0x36,0x02,0x04,0x00,0x38,0x00,0x01,0x02, - 0x58,0x01,0x0f,0x80,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02, - 0x07,0x01,0x05,0x00,0x58,0x01,0x0a,0x80,0x36,0x01,0x06,0x00,0x12,0x03,0x00,0x00, - 0x42,0x01,0x02,0x04,0x48,0x04,0x04,0x80,0x36,0x06,0x07,0x00,0x12,0x08,0x05,0x00, - 0x42,0x06,0x02,0x02,0x3c,0x06,0x04,0x00,0x46,0x04,0x03,0x03,0x52,0x04,0xfa,0x7f, - 0x4c,0x00,0x02,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67, - 0x0a,0x70,0x61,0x69,0x72,0x73,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72, - 0x73,0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74, - 0x79,0x70,0x65,0xe2,0x06,0x00,0x01,0x15,0x00,0x16,0x01,0xb0,0x01,0x2b,0x01,0x02, - 0x00,0x2b,0x02,0x01,0x00,0x2c,0x03,0x09,0x00,0x29,0x0a,0x01,0x00,0x15,0x0b,0x00, - 0x00,0x03,0x0a,0x0b,0x00,0x58,0x0b,0xa8,0x80,0x55,0x0b,0xa7,0x80,0x38,0x0b,0x0a, - 0x00,0x34,0x0c,0x00,0x00,0x36,0x0d,0x00,0x00,0x12,0x0f,0x0b,0x00,0x42,0x0d,0x02, - 0x04,0x58,0x10,0x08,0x80,0x09,0x10,0x00,0x00,0x58,0x12,0x02,0x80,0x3c,0x11,0x10, - 0x0c,0x58,0x12,0x04,0x80,0x36,0x12,0x01,0x00,0x12,0x14,0x11,0x00,0x42,0x12,0x02, - 0x02,0x3c,0x12,0x10,0x0c,0x45,0x10,0x03,0x03,0x52,0x10,0xf6,0x7f,0x36,0x0d,0x02, - 0x00,0x39,0x0d,0x03,0x0d,0x12,0x0f,0x0c,0x00,0x29,0x10,0x01,0x00,0x42,0x0d,0x03, - 0x02,0x36,0x0e,0x04,0x00,0x38,0x0e,0x0d,0x0e,0x0f,0x00,0x0e,0x00,0x58,0x0f,0x0e, - 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x0f,0x0e,0x00,0x36,0x11,0x05, - 0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02,0x00,0x41,0x0f,0x00,0x02,0x36,0x10,0x06, - 0x00,0x38,0x10,0x0d,0x10,0x0e,0x00,0x10,0x00,0x58,0x10,0x81,0x80,0x36,0x10,0x07, - 0x00,0x3d,0x0f,0x08,0x10,0x58,0x0f,0x7e,0x80,0x07,0x0d,0x09,0x00,0x58,0x0f,0x08, - 0x80,0x36,0x0f,0x0a,0x00,0x36,0x11,0x05,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02, - 0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02,0x01,0x00,0x58,0x0f,0x74, - 0x80,0x07,0x0d,0x0b,0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x02, - 0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x6e,0x80,0x0e,0x00,0x02,0x00,0x58,0x0f,0x6c, - 0x80,0x36,0x0f,0x0a,0x00,0x36,0x11,0x05,0x00,0x12,0x13,0x0c,0x00,0x42,0x11,0x02, - 0x00,0x41,0x0f,0x00,0x02,0x12,0x01,0x0f,0x00,0x12,0x02,0x01,0x00,0x58,0x0f,0x64, - 0x80,0x07,0x0d,0x0c,0x00,0x58,0x0f,0x08,0x80,0x0e,0x00,0x01,0x00,0x58,0x0f,0x02, - 0x80,0x13,0x01,0x02,0x00,0x58,0x0f,0x5e,0x80,0x2b,0x01,0x01,0x00,0x58,0x0f,0x01, - 0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x5a,0x80,0x07,0x0d,0x0d,0x00,0x58,0x0f,0x02, - 0x80,0x2b,0x01,0x02,0x00,0x58,0x0f,0x56,0x80,0x07,0x0d,0x0e,0x00,0x58,0x0f,0x0b, - 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x09,0x80,0x12,0x03,0x0a,0x00,0x27,0x05,0x0f, - 0x00,0x3a,0x04,0x01,0x0c,0x3a,0x06,0x02,0x0c,0x29,0x07,0x01,0x00,0x36,0x0f,0x07, - 0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04,0x0f,0x58,0x0f,0x49,0x80,0x07,0x0d,0x10, - 0x00,0x58,0x0f,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x0c,0x80,0x12,0x03,0x0a, - 0x00,0x27,0x05,0x11,0x00,0x3a,0x04,0x01,0x0c,0x3a,0x08,0x03,0x0c,0x3a,0x0f,0x04, - 0x0c,0x0c,0x09,0x0f,0x00,0x58,0x10,0x01,0x80,0x29,0x09,0x01,0x00,0x36,0x0f,0x07, - 0x00,0x3a,0x10,0x02,0x0c,0x3c,0x10,0x04,0x0f,0x58,0x0f,0x39,0x80,0x07,0x0d,0x12, - 0x00,0x58,0x0f,0x27,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x25,0x80,0x07,0x05,0x0f, - 0x00,0x58,0x0f,0x09,0x80,0x16,0x07,0x00,0x07,0x15,0x0f,0x06,0x00,0x03,0x07,0x0f, - 0x00,0x58,0x0f,0x2f,0x80,0x36,0x0f,0x07,0x00,0x38,0x10,0x07,0x06,0x3c,0x10,0x04, - 0x0f,0x12,0x0a,0x03,0x00,0x58,0x0f,0x2a,0x80,0x07,0x05,0x11,0x00,0x58,0x0f,0x16, - 0x80,0x36,0x0f,0x07,0x00,0x36,0x10,0x07,0x00,0x38,0x10,0x04,0x10,0x20,0x10,0x09, - 0x10,0x3c,0x10,0x04,0x0f,0x29,0x0f,0x00,0x00,0x01,0x0f,0x09,0x00,0x58,0x0f,0x04, - 0x80,0x36,0x0f,0x07,0x00,0x38,0x0f,0x04,0x0f,0x00,0x08,0x0f,0x00,0x58,0x0f,0x1c, - 0x80,0x29,0x0f,0x00,0x00,0x01,0x09,0x0f,0x00,0x58,0x0f,0x05,0x80,0x36,0x0f,0x07, - 0x00,0x38,0x0f,0x04,0x0f,0x01,0x0f,0x08,0x00,0x58,0x0f,0x01,0x80,0x58,0x0f,0x14, - 0x80,0x12,0x0a,0x03,0x00,0x58,0x0f,0x12,0x80,0x29,0x0a,0x00,0x00,0x58,0x0f,0x10, - 0x80,0x07,0x0d,0x13,0x00,0x58,0x0f,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x04, - 0x80,0x36,0x0f,0x05,0x00,0x12,0x11,0x0c,0x00,0x44,0x0f,0x02,0x00,0x58,0x0f,0x08, - 0x80,0x0f,0x00,0x01,0x00,0x58,0x0f,0x06,0x80,0x36,0x0f,0x14,0x00,0x2b,0x11,0x01, - 0x00,0x27,0x12,0x15,0x00,0x12,0x13,0x0d,0x00,0x26,0x12,0x13,0x12,0x42,0x0f,0x03, - 0x01,0x16,0x0a,0x00,0x0a,0x58,0x0b,0x55,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f, - 0x6d,0x6d,0x61,0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a, - 0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09, - 0x6c,0x6f,0x6f,0x70,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x09, - 0x65,0x61,0x63,0x68,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64, - 0x09,0x65,0x6c,0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07, - 0x69,0x66,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76, - 0x61,0x72,0x73,0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b, - 0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61, - 0x62,0x6c,0x65,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0b, - 0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00,0x0f,0x01,0x7b, - 0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a,0x01,0x01,0x00, - 0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b,0x05,0x01,0x00, - 0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x01,0x00, - 0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58,0x06,0x07,0x80, - 0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00, - 0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b,0x01,0x00,0x00, - 0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58,0x06,0x3b,0x80, - 0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58,0x06,0x02,0x80, - 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x33,0x80, - 0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58,0x06,0x02,0x80, - 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x2b,0x80, - 0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58,0x06,0x02,0x80, - 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x23,0x80, - 0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58,0x06,0x02,0x80, - 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x1b,0x80, - 0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58,0x06,0x02,0x80, - 0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x13,0x80, - 0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39,0x06,0x08,0x06, - 0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b,0x06,0x00,0x00, - 0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00, - 0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27,0x09,0x0a,0x00, - 0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f,0x00,0x04,0x00, - 0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29,0x07,0x03,0x00, - 0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36,0x06,0x0b,0x00, - 0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15,0x0c,0x00,0x00, - 0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58,0x07,0x05,0x80, - 0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00, - 0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c,0x07,0x05,0x00, - 0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x06,0x80, - 0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12,0x0b,0x02,0x00, - 0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07,0x6f,0x72,0x08, - 0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76,0x61,0x6c,0x19, - 0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20,0x6b,0x6e,0x6f, - 0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d,0x61,0x74,0x63, - 0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d,0x06,0x21,0x08, - 0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80,0xc0,0x99,0x04, - 0xab,0x05,0x00,0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02,0x00,0x00,0x12,0x04,0x00, - 0x00,0x42,0x02,0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02,0x04,0x80,0x36,0x02,0x02, - 0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00,0x02,0x00,0x36,0x02,0x03, - 0x00,0x36,0x04,0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06,0x00,0x00,0x27,0x07,0x05, - 0x00,0x42,0x04,0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04,0x02,0x80,0x2b,0x04,0x01, - 0x00,0x58,0x05,0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05,0x06,0x00,0x42,0x02,0x03, - 0x01,0x36,0x02,0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04,0x00,0x00,0x27,0x05,0x08, - 0x00,0x27,0x06,0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04,0x03,0x00,0x29,0x06,0x01, - 0x00,0x02,0x03,0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06,0x01,0x00,0x58,0x07,0x01, - 0x80,0x2b,0x06,0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04,0x03,0x01,0x09,0x03,0x00, - 0x00,0x58,0x04,0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07,0x01,0x00,0x39,0x05,0x0b, - 0x01,0x42,0x05,0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05,0x02,0x80,0x29,0x04,0x12, - 0x00,0x58,0x05,0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05,0x0e,0x05,0x12,0x07,0x01, - 0x00,0x27,0x08,0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04,0x05,0x00,0x36,0x05,0x03, - 0x00,0x29,0x07,0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07,0x03,0x80,0x29,0x07,0x12, - 0x00,0x02,0x04,0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07,0x01,0x00,0x58,0x08,0x01, - 0x80,0x2b,0x07,0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05,0x03,0x01,0x36,0x05,0x01, - 0x00,0x39,0x05,0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08,0x00,0x00,0x27,0x09,0x11, - 0x00,0x26,0x07,0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05,0x03,0x03,0x15,0x07,0x06, - 0x00,0x21,0x07,0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08,0x07,0x00,0x58,0x08,0x08, - 0x80,0x12,0x08,0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09,0x13,0x09,0x27,0x0b,0x11, - 0x00,0x12,0x0c,0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06,0x09,0x08,0x58,0x08,0x0a, - 0x80,0x29,0x08,0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08,0x07,0x80,0x36,0x08,0x01, - 0x00,0x39,0x08,0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b,0x01,0x00,0x12,0x0c,0x04, - 0x00,0x42,0x08,0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08,0x05,0x00,0x12,0x09,0x06, - 0x00,0x26,0x00,0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08,0x07,0x08,0x12,0x0a,0x00, - 0x00,0x27,0x0b,0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d,0x01,0x00,0x42,0x08,0x05, - 0x02,0x12,0x00,0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08,0x01,0x00,0x58,0x08,0x01, - 0x80,0x27,0x00,0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04,0x17,0x04,0x12,0x06,0x00, - 0x00,0x44,0x04,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67, - 0x6e,0x75,0x6d,0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08,0x72,0x65,0x70,0x11,0x28, - 0x25,0x64,0x2b,0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29,0x06,0x30,0x20,0x74,0x6f, - 0x6b,0x65,0x6e,0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64, - 0x20,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64,0x65,0x63,0x69,0x6d,0x61, - 0x6c,0x73,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, - 0x0a,0x61,0x65,0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65,0x72,0x1a,0x74,0x68,0x65, - 0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c, - 0x69,0x64,0x05,0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62,0x2a,0x74,0x68,0x65,0x20, - 0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x20, - 0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65, - 0x72,0x0c,0x5b,0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b, - 0x61,0x73,0x73,0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x0b, - 0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65,0x02,0x00,0x86,0x05,0x03, - 0x00,0x03,0x00,0x49,0x00,0x4d,0x34,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x35,0x00, - 0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33,0x01,0x03,0x00,0x3d,0x01, - 0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33,0x01,0x08,0x00,0x3d,0x01, - 0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33,0x01,0x0c,0x00,0x3d,0x01, - 0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33,0x01,0x10,0x00,0x3d,0x01, - 0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33,0x01,0x14,0x00,0x3d,0x01, - 0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33,0x01,0x18,0x00,0x3d,0x01, - 0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33,0x01,0x1c,0x00,0x3d,0x01, - 0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33,0x01,0x20,0x00,0x3d,0x01, - 0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33,0x01,0x24,0x00,0x3d,0x01, - 0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33,0x01,0x28,0x00,0x3d,0x01, - 0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33,0x01,0x2c,0x00,0x3d,0x01, - 0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33,0x01,0x30,0x00,0x3d,0x01, - 0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33,0x01,0x34,0x00,0x3d,0x01, - 0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33,0x01,0x38,0x00,0x3d,0x01, - 0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33,0x01,0x3c,0x00,0x3d,0x01, - 0x3d,0x00,0x37,0x00,0x3e,0x00,0x33,0x00,0x3f,0x00,0x37,0x00,0x40,0x00,0x33,0x00, - 0x41,0x00,0x37,0x00,0x42,0x00,0x33,0x00,0x43,0x00,0x37,0x00,0x44,0x00,0x33,0x00, - 0x45,0x00,0x37,0x00,0x46,0x00,0x36,0x00,0x47,0x00,0x39,0x00,0x48,0x00,0x36,0x02, - 0x42,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d,0x72,0x65,0x67,0x69,0x73, - 0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f, - 0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61,0x6c,0x00,0x0c,0x65,0x78, - 0x65,0x63,0x75,0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61, - 0x72,0x67,0x00,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72, - 0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a, - 0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74, - 0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75, - 0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64, - 0x00,0x0b,0x73,0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74, - 0x00,0x09,0x73,0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77, - 0x00,0x08,0x64,0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00, - 0x08,0x61,0x64,0x64,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e, - 0x73,0x65,0x72,0x74,0x00,0x08,0x73,0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a, - 0x73,0x74,0x6f,0x72,0x65,0x00,0x08,0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64, - 0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c, - 0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61, - 0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00, - 0x00,0x09,0x73,0x6b,0x69,0x70,0x01,0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74, - 0x02,0x08,0x6c,0x65,0x74,0x02,0x0a,0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73,0x65, - 0x6e,0x64,0x02,0x08,0x73,0x65,0x74,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02, - 0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22, - 0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67,0x65, - 0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, - 0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65,0x78, - 0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74, - 0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61,0x6c, - 0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d, + 0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08,0x72,0x65,0x70,0x11,0x28,0x25,0x64,0x2b, + 0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29,0x06,0x30,0x20,0x74,0x6f,0x6b,0x65,0x6e, + 0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x64,0x65, + 0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x09, + 0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x0a,0x61,0x65, + 0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65,0x72,0x1a,0x74,0x68,0x65,0x20,0x61,0x6d, + 0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x05, + 0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62,0x2a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f, + 0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x20,0x69,0x6e,0x76, + 0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x0c,0x5b, + 0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b,0x61,0x73,0x73, + 0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x0b,0x73,0x74,0x72, + 0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65,0x02,0x00,0xba,0x05,0x03,0x00,0x03,0x00, + 0x4f,0x00,0x53,0x34,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37, + 0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33,0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33, + 0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33,0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33, + 0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33,0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33, + 0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33,0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33, + 0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33,0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33, + 0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33,0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33, + 0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33,0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33, + 0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33,0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33, + 0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33,0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33, + 0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33,0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33, + 0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33,0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33, + 0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33,0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33, + 0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33,0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33, + 0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33,0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33, + 0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33,0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x33, + 0x01,0x3e,0x00,0x3d,0x01,0x3f,0x00,0x33,0x01,0x40,0x00,0x3d,0x01,0x41,0x00,0x33, + 0x01,0x42,0x00,0x3d,0x01,0x43,0x00,0x37,0x00,0x44,0x00,0x33,0x00,0x45,0x00,0x37, + 0x00,0x46,0x00,0x33,0x00,0x47,0x00,0x37,0x00,0x48,0x00,0x33,0x00,0x49,0x00,0x37, + 0x00,0x4a,0x00,0x33,0x00,0x4b,0x00,0x37,0x00,0x4c,0x00,0x36,0x00,0x4d,0x00,0x39, + 0x00,0x4e,0x00,0x36,0x02,0x48,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d, + 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e, + 0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61, + 0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63, + 0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x00,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b, + 0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e, + 0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69, + 0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f, + 0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00, + 0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73,0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66, + 0x6f,0x72,0x6d,0x61,0x74,0x00,0x0b,0x63,0x6f,0x6e,0x63,0x61,0x74,0x00,0x09,0x73, + 0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64, + 0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64, + 0x64,0x00,0x0d,0x67,0x65,0x74,0x5f,0x6b,0x65,0x79,0x73,0x00,0x0d,0x67,0x65,0x74, + 0x5f,0x73,0x69,0x7a,0x65,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69, + 0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73,0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00, + 0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08,0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e, + 0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c, + 0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63, + 0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00, + 0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01,0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72, + 0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a,0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73, + 0x65,0x6e,0x64,0x02,0x08,0x73,0x65,0x74,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74, + 0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, + 0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67, + 0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69, + 0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65, + 0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e, + 0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61, + 0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d } diff --git a/contract/vm_multicall.lua b/contract/vm_multicall.lua index 6997917ef..dc7f25991 100644 --- a/contract/vm_multicall.lua +++ b/contract/vm_multicall.lua @@ -15,7 +15,7 @@ action = { ["pcall-send"] = function (amount,...) return {pcall(contract.call.value(amount),...)} end, -- aergo balance and transfer - balance = function (address) return contract.balance(address) end, + balance = function (address) return bignum.number(contract.balance(address)) end, send = function (address,amount) return contract.send(address, amount) end, -- variables @@ -26,7 +26,16 @@ action = { get = function (o,k) return o[k] end, set = function (o,k,v) o[k] = v end, insert = function (...) table.insert(...) end, -- inserts at the end if no pos informed - remove = function (...) table.remove(...) end, -- returns the removed item + remove = function (...) return table.remove(...) end, -- returns the removed item + get_size = function (x) return #x end, + get_keys = function (obj) + local list = {} + for key,_ in pairs(obj) do + list[#list + 1] = key + end + table.sort(list) -- for a deterministic output + return list + end, -- math add = function (x,y) return x+y end, @@ -38,6 +47,7 @@ action = { sqrt = function (x) return bignum.sqrt(x) end, -- use pow(0.5) for numbers -- strings + concat = function (...) return table.concat({...}) end, format = function (...) return string.format(...) end, -- for concat: ['format','%s%s','%val1%','%val2%'] substr = function (...) return string.sub(...) end, find = function (...) return string.match(...) end, @@ -75,9 +85,10 @@ function execute(calls) local if_done = false local for_cmdpos - local for_var, for_type - local for_list, for_pos + local for_var, for_var2, for_type + local for_obj, for_list, for_pos local for_last, for_increment + local skip_for = false local cmdpos = 1 while cmdpos <= #calls do @@ -118,14 +129,16 @@ function execute(calls) elseif cmd == "end" then if_on = true - -- for foreach loop + -- for foreach forpair break loop elseif cmd == "foreach" and if_on then - for_cmdpos = cmdpos - for_type = "each" - for_var = args[1] + for_var2 = "__" + for_obj = {} for_list = args[2] - for_pos = 1 - vars[for_var] = for_list[for_pos] + elseif cmd == "forpair" and if_on then + for_var2 = args[2] + for_obj = args[3] + for_list = action["get_keys"](for_obj) + vars[for_var2] = for_obj[for_list[1]] elseif cmd == "for" and if_on then for_cmdpos = cmdpos for_type = "number" @@ -133,11 +146,15 @@ function execute(calls) for_last = args[3] for_increment = args[4] or 1 vars[for_var] = args[2] + skip_for = ((for_increment > 0 and vars[for_var] > for_last) or (for_increment < 0 and vars[for_var] < for_last)) + elseif cmd == "break" and if_on then + skip_for = true elseif cmd == "loop" and if_on then if for_type == "each" then for_pos = for_pos + 1 if for_pos <= #for_list then vars[for_var] = for_list[for_pos] + vars[for_var2] = for_obj[for_list[for_pos]] cmdpos = for_cmdpos end elseif for_type == "number" then @@ -158,6 +175,23 @@ function execute(calls) assert(false, "command not found: " .. cmd) end + if if_on and (cmd == "foreach" or cmd == "forpair") then + for_cmdpos = cmdpos + for_type = "each" + for_var = args[1] + for_pos = 1 + vars[for_var] = for_list[1] + skip_for = (for_list[1] == nil) -- if the list is empty or it is a dictionary + end + + if skip_for then + repeat + cmdpos = cmdpos + 1 + call = calls[cmdpos] + until call == nil or call[1] == "loop" + skip_for = false + end + cmdpos = cmdpos + 1 end From 5c1def2e95c05ea9be0ed9be900f86d76bc8c354 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Wed, 27 Jul 2022 03:28:41 -0300 Subject: [PATCH 07/49] [contract] add 'break if' to composable transactions --- contract/vm_multicall.go | 366 +++++++++++++++++++------------------- contract/vm_multicall.lua | 6 +- 2 files changed, 190 insertions(+), 182 deletions(-) diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go index fe9864826..5ea72b586 100644 --- a/contract/vm_multicall.go +++ b/contract/vm_multicall.go @@ -1,7 +1,7 @@ package contract var multicall_payload = []byte { - 0x62,0x12,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, + 0x9a,0x12,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, 0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00, 0x00,0x00,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, 0x37,0x02,0x01,0x04,0x00,0x03,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, @@ -99,9 +99,9 @@ var multicall_payload = []byte { 0x00,0x02,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0a, 0x70,0x61,0x69,0x72,0x73,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72,0x73, 0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79, - 0x70,0x65,0x90,0x09,0x00,0x01,0x18,0x00,0x1a,0x01,0xf5,0x01,0x2b,0x01,0x02,0x00, + 0x70,0x65,0xc8,0x09,0x00,0x01,0x18,0x00,0x1a,0x01,0x83,0x02,0x2b,0x01,0x02,0x00, 0x2b,0x02,0x01,0x00,0x2c,0x03,0x0b,0x00,0x2b,0x0c,0x01,0x00,0x29,0x0d,0x01,0x00, - 0x15,0x0e,0x00,0x00,0x03,0x0d,0x0e,0x00,0x58,0x0e,0xec,0x80,0x55,0x0e,0xeb,0x80, + 0x15,0x0e,0x00,0x00,0x03,0x0d,0x0e,0x00,0x58,0x0e,0xfa,0x80,0x55,0x0e,0xf9,0x80, 0x38,0x0e,0x0d,0x00,0x34,0x0f,0x00,0x00,0x36,0x10,0x00,0x00,0x12,0x12,0x0e,0x00, 0x42,0x10,0x02,0x04,0x58,0x13,0x08,0x80,0x09,0x13,0x00,0x00,0x58,0x15,0x02,0x80, 0x3c,0x14,0x13,0x0f,0x58,0x15,0x04,0x80,0x36,0x15,0x01,0x00,0x12,0x17,0x14,0x00, @@ -110,24 +110,24 @@ var multicall_payload = []byte { 0x42,0x10,0x03,0x02,0x36,0x11,0x04,0x00,0x38,0x11,0x10,0x11,0x0f,0x00,0x11,0x00, 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x12,0x12,0x11,0x00, 0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00,0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02, - 0x36,0x13,0x06,0x00,0x38,0x13,0x10,0x13,0x0e,0x00,0x13,0x00,0x58,0x13,0xa7,0x80, - 0x36,0x13,0x07,0x00,0x3d,0x12,0x08,0x13,0x58,0x12,0xa4,0x80,0x07,0x10,0x09,0x00, + 0x36,0x13,0x06,0x00,0x38,0x13,0x10,0x13,0x0e,0x00,0x13,0x00,0x58,0x13,0xb5,0x80, + 0x36,0x13,0x07,0x00,0x3d,0x12,0x08,0x13,0x58,0x12,0xb2,0x80,0x07,0x10,0x09,0x00, 0x58,0x12,0x08,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, - 0x58,0x12,0x9a,0x80,0x07,0x10,0x0b,0x00,0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00, - 0x58,0x12,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x12,0x94,0x80,0x0e,0x00,0x02,0x00, - 0x58,0x12,0x92,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, + 0x58,0x12,0xa8,0x80,0x07,0x10,0x0b,0x00,0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00, + 0x58,0x12,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x12,0xa2,0x80,0x0e,0x00,0x02,0x00, + 0x58,0x12,0xa0,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, - 0x58,0x12,0x8a,0x80,0x07,0x10,0x0c,0x00,0x58,0x12,0x08,0x80,0x0e,0x00,0x01,0x00, - 0x58,0x12,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x12,0x84,0x80,0x2b,0x01,0x01,0x00, - 0x58,0x12,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x80,0x80,0x07,0x10,0x0d,0x00, - 0x58,0x12,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x7c,0x80,0x07,0x10,0x0e,0x00, + 0x58,0x12,0x98,0x80,0x07,0x10,0x0c,0x00,0x58,0x12,0x08,0x80,0x0e,0x00,0x01,0x00, + 0x58,0x12,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x12,0x92,0x80,0x2b,0x01,0x01,0x00, + 0x58,0x12,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x8e,0x80,0x07,0x10,0x0d,0x00, + 0x58,0x12,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x8a,0x80,0x07,0x10,0x0e,0x00, 0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x04,0x80,0x27,0x05,0x0f,0x00, - 0x34,0x07,0x00,0x00,0x3a,0x08,0x02,0x0f,0x58,0x12,0x74,0x80,0x07,0x10,0x10,0x00, + 0x34,0x07,0x00,0x00,0x3a,0x08,0x02,0x0f,0x58,0x12,0x82,0x80,0x07,0x10,0x10,0x00, 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x3a,0x05,0x02,0x0f, 0x3a,0x07,0x03,0x0f,0x36,0x12,0x04,0x00,0x39,0x12,0x11,0x12,0x12,0x14,0x07,0x00, 0x42,0x12,0x02,0x02,0x12,0x08,0x12,0x00,0x36,0x12,0x07,0x00,0x3a,0x13,0x01,0x08, - 0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x58,0x12,0x64,0x80,0x07,0x10,0x12,0x00, + 0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x58,0x12,0x72,0x80,0x07,0x10,0x12,0x00, 0x58,0x12,0x1f,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x1d,0x80,0x12,0x03,0x0d,0x00, 0x27,0x06,0x13,0x00,0x3a,0x04,0x01,0x0f,0x3a,0x0a,0x03,0x0f,0x3a,0x12,0x04,0x0f, 0x0c,0x0b,0x12,0x00,0x58,0x13,0x01,0x80,0x29,0x0b,0x01,0x00,0x36,0x12,0x07,0x00, @@ -135,171 +135,175 @@ var multicall_payload = []byte { 0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00, 0x58,0x12,0x09,0x80,0x29,0x12,0x00,0x00,0x01,0x0b,0x12,0x00,0x58,0x12,0x04,0x80, 0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x12,0x0a,0x00,0x58,0x12,0x02,0x80, - 0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x43,0x80, - 0x07,0x10,0x14,0x00,0x58,0x12,0x04,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x02,0x80, - 0x2b,0x0c,0x02,0x00,0x58,0x12,0x3d,0x80,0x07,0x10,0x15,0x00,0x58,0x12,0x2b,0x80, - 0x0f,0x00,0x01,0x00,0x58,0x12,0x29,0x80,0x07,0x06,0x16,0x00,0x58,0x12,0x0d,0x80, - 0x16,0x09,0x00,0x09,0x15,0x12,0x08,0x00,0x03,0x09,0x12,0x00,0x58,0x12,0x33,0x80, - 0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08,0x3c,0x13,0x04,0x12,0x36,0x12,0x07,0x00, - 0x38,0x13,0x09,0x08,0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x12,0x0d,0x03,0x00, - 0x58,0x12,0x2a,0x80,0x07,0x06,0x13,0x00,0x58,0x12,0x16,0x80,0x36,0x12,0x07,0x00, - 0x36,0x13,0x07,0x00,0x38,0x13,0x04,0x13,0x20,0x13,0x0b,0x13,0x3c,0x13,0x04,0x12, - 0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00,0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00, - 0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00,0x58,0x12,0x1c,0x80,0x29,0x12,0x00,0x00, - 0x01,0x0b,0x12,0x00,0x58,0x12,0x05,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12, - 0x01,0x12,0x0a,0x00,0x58,0x12,0x01,0x80,0x58,0x12,0x14,0x80,0x12,0x0d,0x03,0x00, - 0x58,0x12,0x12,0x80,0x29,0x0d,0x00,0x00,0x58,0x12,0x10,0x80,0x07,0x10,0x17,0x00, - 0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x04,0x80,0x36,0x12,0x05,0x00, - 0x12,0x14,0x0f,0x00,0x44,0x12,0x02,0x00,0x58,0x12,0x08,0x80,0x0f,0x00,0x01,0x00, - 0x58,0x12,0x06,0x80,0x36,0x12,0x18,0x00,0x2b,0x14,0x01,0x00,0x27,0x15,0x19,0x00, - 0x12,0x16,0x10,0x00,0x26,0x15,0x16,0x15,0x42,0x12,0x03,0x01,0x0f,0x00,0x01,0x00, - 0x58,0x12,0x11,0x80,0x06,0x10,0x0e,0x00,0x58,0x12,0x02,0x80,0x07,0x10,0x10,0x00, - 0x58,0x12,0x0d,0x80,0x12,0x03,0x0d,0x00,0x27,0x06,0x16,0x00,0x3a,0x04,0x01,0x0f, - 0x29,0x09,0x01,0x00,0x36,0x12,0x07,0x00,0x3a,0x13,0x01,0x08,0x3c,0x13,0x04,0x12, - 0x3a,0x12,0x01,0x08,0x0a,0x12,0x00,0x00,0x58,0x12,0x02,0x80,0x2b,0x0c,0x01,0x00, - 0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x0f,0x00,0x0c,0x00,0x58,0x12,0x09,0x80, - 0x55,0x12,0x07,0x80,0x16,0x0d,0x00,0x0d,0x38,0x0e,0x0d,0x00,0x0a,0x0e,0x00,0x00, - 0x58,0x12,0x03,0x80,0x3a,0x12,0x01,0x0e,0x07,0x12,0x15,0x00,0x58,0x12,0xf8,0x7f, - 0x2b,0x0c,0x01,0x00,0x16,0x0d,0x00,0x0d,0x58,0x0e,0x11,0x7f,0x4b,0x00,0x01,0x00, - 0x18,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75, - 0x6e,0x64,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75, - 0x72,0x6e,0x09,0x65,0x61,0x63,0x68,0x09,0x6c,0x6f,0x6f,0x70,0x0a,0x62,0x72,0x65, - 0x61,0x6b,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x08,0x66,0x6f,0x72,0x0d,0x67,0x65, - 0x74,0x5f,0x6b,0x65,0x79,0x73,0x0c,0x66,0x6f,0x72,0x70,0x61,0x69,0x72,0x07,0x5f, - 0x5f,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63,0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c, - 0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09,0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10, - 0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73, - 0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74, - 0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65, - 0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0b,0x69,0x70,0x61, - 0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00,0x0d,0x00,0x0f,0x01,0x7b,0x34,0x00,0x03, - 0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00,0x00,0x3a,0x01,0x01,0x00,0x3a,0x02,0x02, - 0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01,0x00,0x2b,0x05,0x01,0x00,0x36,0x06,0x00, - 0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x01,0x00,0x29,0x0a,0x01, - 0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02,0x00,0x58,0x06,0x07,0x80,0x2b,0x04,0x02, - 0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x02, - 0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06,0x00,0x0b,0x01,0x00,0x00,0x58,0x06,0x03, - 0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01,0x80,0x58,0x06,0x3b,0x80,0x07,0x02,0x03, - 0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, - 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x33,0x80,0x07,0x02,0x04, - 0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, - 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x2b,0x80,0x07,0x02,0x05, - 0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, - 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x23,0x80,0x07,0x02,0x06, - 0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, - 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x1b,0x80,0x07,0x02,0x07, - 0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01, - 0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x13,0x80,0x07,0x02,0x08, - 0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00,0x00,0x39,0x06,0x08,0x06,0x12,0x08,0x01, - 0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03,0x02,0x0b,0x06,0x00,0x00,0x58,0x06,0x02, - 0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x06, - 0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01,0x00,0x27,0x09,0x0a,0x00,0x12,0x0a,0x02, - 0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03,0x01,0x0f,0x00,0x04,0x00,0x58,0x06,0x01, - 0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00,0x00,0x29,0x07,0x03,0x00,0x01,0x07,0x06, - 0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04,0x00,0x36,0x06,0x0b,0x00,0x36,0x08,0x0c, - 0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05,0x00,0x15,0x0c,0x00,0x00,0x42,0x08,0x04, - 0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d,0x00,0x58,0x07,0x05,0x80,0x0d,0x07,0x05, - 0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x0d, - 0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05,0x80,0x0c,0x07,0x05,0x00,0x58,0x07,0x01, - 0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x06,0x80,0x36,0x07,0x09, - 0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a,0x00,0x12,0x0b,0x02,0x00,0x26,0x0a,0x0b, - 0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02,0x00,0x07,0x6f,0x72,0x08,0x61,0x6e,0x64, - 0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09,0x65,0x76,0x61,0x6c,0x19,0x6f,0x70,0x65, - 0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f,0x74,0x20,0x6b,0x6e,0x6f,0x77,0x6e,0x3a, - 0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0a,0x6d,0x61,0x74,0x63,0x68,0x07,0x3c, - 0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e,0x06,0x3d,0x06,0x21,0x08,0x73,0x75,0x62, - 0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03,0x80,0x80,0xc0,0x99,0x04,0xab,0x05,0x00, - 0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02,0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02, - 0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02,0x04,0x80,0x36,0x02,0x02,0x00,0x12,0x04, - 0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00,0x02,0x00,0x36,0x02,0x03,0x00,0x36,0x04, - 0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06,0x00,0x00,0x27,0x07,0x05,0x00,0x42,0x04, - 0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04,0x02,0x80,0x2b,0x04,0x01,0x00,0x58,0x05, - 0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05,0x06,0x00,0x42,0x02,0x03,0x01,0x36,0x02, - 0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04,0x00,0x00,0x27,0x05,0x08,0x00,0x27,0x06, - 0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04,0x03,0x00,0x29,0x06,0x01,0x00,0x02,0x03, - 0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06,0x01,0x00,0x58,0x07,0x01,0x80,0x2b,0x06, - 0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04,0x03,0x01,0x09,0x03,0x00,0x00,0x58,0x04, - 0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07,0x01,0x00,0x39,0x05,0x0b,0x01,0x42,0x05, - 0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05,0x02,0x80,0x29,0x04,0x12,0x00,0x58,0x05, - 0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05,0x0e,0x05,0x12,0x07,0x01,0x00,0x27,0x08, - 0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04,0x05,0x00,0x36,0x05,0x03,0x00,0x29,0x07, - 0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07,0x03,0x80,0x29,0x07,0x12,0x00,0x02,0x04, - 0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07,0x01,0x00,0x58,0x08,0x01,0x80,0x2b,0x07, - 0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05,0x03,0x01,0x36,0x05,0x01,0x00,0x39,0x05, - 0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08,0x00,0x00,0x27,0x09,0x11,0x00,0x26,0x07, - 0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05,0x03,0x03,0x15,0x07,0x06,0x00,0x21,0x07, - 0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08,0x07,0x00,0x58,0x08,0x08,0x80,0x12,0x08, - 0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09,0x13,0x09,0x27,0x0b,0x11,0x00,0x12,0x0c, - 0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06,0x09,0x08,0x58,0x08,0x0a,0x80,0x29,0x08, - 0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08,0x07,0x80,0x36,0x08,0x01,0x00,0x39,0x08, - 0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b,0x01,0x00,0x12,0x0c,0x04,0x00,0x42,0x08, - 0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08,0x05,0x00,0x12,0x09,0x06,0x00,0x26,0x00, - 0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08,0x07,0x08,0x12,0x0a,0x00,0x00,0x27,0x0b, - 0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d,0x01,0x00,0x42,0x08,0x05,0x02,0x12,0x00, - 0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08,0x01,0x00,0x58,0x08,0x01,0x80,0x27,0x00, - 0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04,0x17,0x04,0x12,0x06,0x00,0x00,0x44,0x04, - 0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d, - 0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08,0x72,0x65,0x70,0x11,0x28,0x25,0x64,0x2b, - 0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29,0x06,0x30,0x20,0x74,0x6f,0x6b,0x65,0x6e, - 0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x64,0x65, - 0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x09, - 0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x0a,0x61,0x65, - 0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65,0x72,0x1a,0x74,0x68,0x65,0x20,0x61,0x6d, - 0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x05, - 0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62,0x2a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f, - 0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x20,0x69,0x6e,0x76, - 0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x0c,0x5b, - 0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b,0x61,0x73,0x73, - 0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x0b,0x73,0x74,0x72, - 0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65,0x02,0x00,0xba,0x05,0x03,0x00,0x03,0x00, - 0x4f,0x00,0x53,0x34,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37, - 0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33,0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33, - 0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33,0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33, - 0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33,0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33, - 0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33,0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33, - 0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33,0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33, - 0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33,0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33, - 0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33,0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33, - 0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33,0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33, - 0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33,0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33, - 0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33,0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33, - 0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33,0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33, - 0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33,0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33, - 0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33,0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33, - 0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33,0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33, - 0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33,0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x33, - 0x01,0x3e,0x00,0x3d,0x01,0x3f,0x00,0x33,0x01,0x40,0x00,0x3d,0x01,0x41,0x00,0x33, - 0x01,0x42,0x00,0x3d,0x01,0x43,0x00,0x37,0x00,0x44,0x00,0x33,0x00,0x45,0x00,0x37, - 0x00,0x46,0x00,0x33,0x00,0x47,0x00,0x37,0x00,0x48,0x00,0x33,0x00,0x49,0x00,0x37, - 0x00,0x4a,0x00,0x33,0x00,0x4b,0x00,0x37,0x00,0x4c,0x00,0x36,0x00,0x4d,0x00,0x39, - 0x00,0x4e,0x00,0x36,0x02,0x48,0x00,0x42,0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d, - 0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e, - 0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61, - 0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63, - 0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x00,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b, - 0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d,0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e, - 0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e,0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69, - 0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f, - 0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00, - 0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73,0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66, - 0x6f,0x72,0x6d,0x61,0x74,0x00,0x0b,0x63,0x6f,0x6e,0x63,0x61,0x74,0x00,0x09,0x73, - 0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64,0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64, - 0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00,0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64, - 0x64,0x00,0x0d,0x67,0x65,0x74,0x5f,0x6b,0x65,0x79,0x73,0x00,0x0d,0x67,0x65,0x74, - 0x5f,0x73,0x69,0x7a,0x65,0x00,0x0b,0x72,0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69, - 0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73,0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00, - 0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08,0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e, - 0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c, - 0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63, - 0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00, - 0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01,0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72, - 0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a,0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73, - 0x65,0x6e,0x64,0x02,0x08,0x73,0x65,0x74,0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74, - 0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b,0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e, - 0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c,0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67, - 0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22,0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69, - 0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65, - 0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c,0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e, - 0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61, - 0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d,0x7d + 0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x51,0x80, + 0x07,0x10,0x14,0x00,0x58,0x12,0x12,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x10,0x80, + 0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14,0x0f,0x00,0x29,0x15,0x01,0x00, + 0x42,0x12,0x03,0x02,0x07,0x12,0x09,0x00,0x58,0x12,0x07,0x80,0x36,0x12,0x0a,0x00, + 0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00,0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02, + 0x12,0x0c,0x12,0x00,0x58,0x12,0x3f,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x3d,0x80, + 0x07,0x10,0x15,0x00,0x58,0x12,0x2b,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x29,0x80, + 0x07,0x06,0x16,0x00,0x58,0x12,0x0d,0x80,0x16,0x09,0x00,0x09,0x15,0x12,0x08,0x00, + 0x03,0x09,0x12,0x00,0x58,0x12,0x33,0x80,0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08, + 0x3c,0x13,0x04,0x12,0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08,0x38,0x13,0x13,0x07, + 0x3c,0x13,0x05,0x12,0x12,0x0d,0x03,0x00,0x58,0x12,0x2a,0x80,0x07,0x06,0x13,0x00, + 0x58,0x12,0x16,0x80,0x36,0x12,0x07,0x00,0x36,0x13,0x07,0x00,0x38,0x13,0x04,0x13, + 0x20,0x13,0x0b,0x13,0x3c,0x13,0x04,0x12,0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00, + 0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00, + 0x58,0x12,0x1c,0x80,0x29,0x12,0x00,0x00,0x01,0x0b,0x12,0x00,0x58,0x12,0x05,0x80, + 0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x01,0x12,0x0a,0x00,0x58,0x12,0x01,0x80, + 0x58,0x12,0x14,0x80,0x12,0x0d,0x03,0x00,0x58,0x12,0x12,0x80,0x29,0x0d,0x00,0x00, + 0x58,0x12,0x10,0x80,0x07,0x10,0x17,0x00,0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00, + 0x58,0x12,0x04,0x80,0x36,0x12,0x05,0x00,0x12,0x14,0x0f,0x00,0x44,0x12,0x02,0x00, + 0x58,0x12,0x08,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x06,0x80,0x36,0x12,0x18,0x00, + 0x2b,0x14,0x01,0x00,0x27,0x15,0x19,0x00,0x12,0x16,0x10,0x00,0x26,0x15,0x16,0x15, + 0x42,0x12,0x03,0x01,0x0f,0x00,0x01,0x00,0x58,0x12,0x11,0x80,0x06,0x10,0x0e,0x00, + 0x58,0x12,0x02,0x80,0x07,0x10,0x10,0x00,0x58,0x12,0x0d,0x80,0x12,0x03,0x0d,0x00, + 0x27,0x06,0x16,0x00,0x3a,0x04,0x01,0x0f,0x29,0x09,0x01,0x00,0x36,0x12,0x07,0x00, + 0x3a,0x13,0x01,0x08,0x3c,0x13,0x04,0x12,0x3a,0x12,0x01,0x08,0x0a,0x12,0x00,0x00, + 0x58,0x12,0x02,0x80,0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00, + 0x0f,0x00,0x0c,0x00,0x58,0x12,0x09,0x80,0x55,0x12,0x07,0x80,0x16,0x0d,0x00,0x0d, + 0x38,0x0e,0x0d,0x00,0x0a,0x0e,0x00,0x00,0x58,0x12,0x03,0x80,0x3a,0x12,0x01,0x0e, + 0x07,0x12,0x15,0x00,0x58,0x12,0xf8,0x7f,0x2b,0x0c,0x01,0x00,0x16,0x0d,0x00,0x0d, + 0x58,0x0e,0x03,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64, + 0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x0b,0x61,0x73,0x73, + 0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09,0x65,0x61,0x63,0x68,0x09, + 0x6c,0x6f,0x6f,0x70,0x0a,0x62,0x72,0x65,0x61,0x6b,0x0b,0x6e,0x75,0x6d,0x62,0x65, + 0x72,0x08,0x66,0x6f,0x72,0x0d,0x67,0x65,0x74,0x5f,0x6b,0x65,0x79,0x73,0x0c,0x66, + 0x6f,0x72,0x70,0x61,0x69,0x72,0x07,0x5f,0x5f,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63, + 0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c,0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09, + 0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73, + 0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e, + 0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f, + 0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73, + 0x5f,0x61,0x72,0x67,0x0b,0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00, + 0x0d,0x00,0x0f,0x01,0x7b,0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00, + 0x00,0x3a,0x01,0x01,0x00,0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01, + 0x00,0x2b,0x05,0x01,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02, + 0x00,0x29,0x09,0x01,0x00,0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02, + 0x00,0x58,0x06,0x07,0x80,0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01, + 0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06, + 0x00,0x0b,0x01,0x00,0x00,0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01, + 0x80,0x58,0x06,0x3b,0x80,0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03, + 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, + 0x00,0x58,0x06,0x33,0x80,0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01, + 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, + 0x00,0x58,0x06,0x2b,0x80,0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01, + 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, + 0x00,0x58,0x06,0x23,0x80,0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03, + 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, + 0x00,0x58,0x06,0x1b,0x80,0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03, + 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, + 0x00,0x58,0x06,0x13,0x80,0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00, + 0x00,0x39,0x06,0x08,0x06,0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03, + 0x02,0x0b,0x06,0x00,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01, + 0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01, + 0x00,0x27,0x09,0x0a,0x00,0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03, + 0x01,0x0f,0x00,0x04,0x00,0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00, + 0x00,0x29,0x07,0x03,0x00,0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04, + 0x00,0x36,0x06,0x0b,0x00,0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05, + 0x00,0x15,0x0c,0x00,0x00,0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d, + 0x00,0x58,0x07,0x05,0x80,0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06, + 0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05, + 0x80,0x0c,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02, + 0x00,0x58,0x07,0x06,0x80,0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a, + 0x00,0x12,0x0b,0x02,0x00,0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02, + 0x00,0x07,0x6f,0x72,0x08,0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09, + 0x65,0x76,0x61,0x6c,0x19,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f, + 0x74,0x20,0x6b,0x6e,0x6f,0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74, + 0x0a,0x6d,0x61,0x74,0x63,0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e, + 0x06,0x3d,0x06,0x21,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03, + 0x80,0x80,0xc0,0x99,0x04,0xab,0x05,0x00,0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02, + 0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02, + 0x04,0x80,0x36,0x02,0x02,0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00, + 0x02,0x00,0x36,0x02,0x03,0x00,0x36,0x04,0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06, + 0x00,0x00,0x27,0x07,0x05,0x00,0x42,0x04,0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04, + 0x02,0x80,0x2b,0x04,0x01,0x00,0x58,0x05,0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05, + 0x06,0x00,0x42,0x02,0x03,0x01,0x36,0x02,0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04, + 0x00,0x00,0x27,0x05,0x08,0x00,0x27,0x06,0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04, + 0x03,0x00,0x29,0x06,0x01,0x00,0x02,0x03,0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06, + 0x01,0x00,0x58,0x07,0x01,0x80,0x2b,0x06,0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04, + 0x03,0x01,0x09,0x03,0x00,0x00,0x58,0x04,0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07, + 0x01,0x00,0x39,0x05,0x0b,0x01,0x42,0x05,0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05, + 0x02,0x80,0x29,0x04,0x12,0x00,0x58,0x05,0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05, + 0x0e,0x05,0x12,0x07,0x01,0x00,0x27,0x08,0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04, + 0x05,0x00,0x36,0x05,0x03,0x00,0x29,0x07,0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07, + 0x03,0x80,0x29,0x07,0x12,0x00,0x02,0x04,0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07, + 0x01,0x00,0x58,0x08,0x01,0x80,0x2b,0x07,0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05, + 0x03,0x01,0x36,0x05,0x01,0x00,0x39,0x05,0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08, + 0x00,0x00,0x27,0x09,0x11,0x00,0x26,0x07,0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05, + 0x03,0x03,0x15,0x07,0x06,0x00,0x21,0x07,0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08, + 0x07,0x00,0x58,0x08,0x08,0x80,0x12,0x08,0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09, + 0x13,0x09,0x27,0x0b,0x11,0x00,0x12,0x0c,0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06, + 0x09,0x08,0x58,0x08,0x0a,0x80,0x29,0x08,0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08, + 0x07,0x80,0x36,0x08,0x01,0x00,0x39,0x08,0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b, + 0x01,0x00,0x12,0x0c,0x04,0x00,0x42,0x08,0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08, + 0x05,0x00,0x12,0x09,0x06,0x00,0x26,0x00,0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08, + 0x07,0x08,0x12,0x0a,0x00,0x00,0x27,0x0b,0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d, + 0x01,0x00,0x42,0x08,0x05,0x02,0x12,0x00,0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08, + 0x01,0x00,0x58,0x08,0x01,0x80,0x27,0x00,0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04, + 0x17,0x04,0x12,0x06,0x00,0x00,0x44,0x04,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65, + 0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08, + 0x72,0x65,0x70,0x11,0x28,0x25,0x64,0x2b,0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29, + 0x06,0x30,0x20,0x74,0x6f,0x6b,0x65,0x6e,0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e, + 0x76,0x61,0x6c,0x69,0x64,0x20,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64, + 0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e, + 0x74,0x72,0x61,0x63,0x74,0x0a,0x61,0x65,0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65, + 0x72,0x1a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20, + 0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x05,0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62, + 0x2a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74, + 0x61,0x69,0x6e,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61, + 0x72,0x61,0x63,0x74,0x65,0x72,0x0c,0x5b,0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d, + 0x61,0x74,0x63,0x68,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74, + 0x72,0x69,0x6e,0x67,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65, + 0x02,0x00,0xba,0x05,0x03,0x00,0x03,0x00,0x4f,0x00,0x53,0x34,0x00,0x00,0x00,0x37, + 0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33, + 0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33, + 0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33, + 0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33, + 0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33, + 0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33, + 0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33, + 0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33, + 0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33, + 0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33, + 0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33, + 0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33, + 0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33, + 0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33, + 0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33, + 0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x33,0x01,0x3e,0x00,0x3d,0x01,0x3f,0x00,0x33, + 0x01,0x40,0x00,0x3d,0x01,0x41,0x00,0x33,0x01,0x42,0x00,0x3d,0x01,0x43,0x00,0x37, + 0x00,0x44,0x00,0x33,0x00,0x45,0x00,0x37,0x00,0x46,0x00,0x33,0x00,0x47,0x00,0x37, + 0x00,0x48,0x00,0x33,0x00,0x49,0x00,0x37,0x00,0x4a,0x00,0x33,0x00,0x4b,0x00,0x37, + 0x00,0x4c,0x00,0x36,0x00,0x4d,0x00,0x39,0x00,0x4e,0x00,0x36,0x02,0x48,0x00,0x42, + 0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, + 0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67, + 0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61,0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75, + 0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x00, + 0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d, + 0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e, + 0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75, + 0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c, + 0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73, + 0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x00,0x0b,0x63, + 0x6f,0x6e,0x63,0x61,0x74,0x00,0x09,0x73,0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64, + 0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64,0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00, + 0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64,0x64,0x00,0x0d,0x67,0x65,0x74,0x5f,0x6b, + 0x65,0x79,0x73,0x00,0x0d,0x67,0x65,0x74,0x5f,0x73,0x69,0x7a,0x65,0x00,0x0b,0x72, + 0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73, + 0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08, + 0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e, + 0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a, + 0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64, + 0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01, + 0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a, + 0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73,0x65,0x6e,0x64,0x02,0x08,0x73,0x65,0x74, + 0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b, + 0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c, + 0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67,0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22, + 0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22, + 0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c, + 0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e, + 0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61,0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d, + 0x7d } diff --git a/contract/vm_multicall.lua b/contract/vm_multicall.lua index dc7f25991..c283711b4 100644 --- a/contract/vm_multicall.lua +++ b/contract/vm_multicall.lua @@ -148,7 +148,11 @@ function execute(calls) vars[for_var] = args[2] skip_for = ((for_increment > 0 and vars[for_var] > for_last) or (for_increment < 0 and vars[for_var] < for_last)) elseif cmd == "break" and if_on then - skip_for = true + if table.remove(args, 1) == "if" then + skip_for = eval(unpack(args)) + else + skip_for = true + end elseif cmd == "loop" and if_on then if for_type == "each" then for_pos = for_pos + 1 From 1f12e79a829020a75e876418014863ab26c566f1 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sun, 7 Aug 2022 15:58:14 -0300 Subject: [PATCH 08/49] [contract] new test cases for composable transactions --- contract/vm_multicall.go | 2 +- contract/vm_test.go | 345 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 327 insertions(+), 20 deletions(-) diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go index 5ea72b586..378565256 100644 --- a/contract/vm_multicall.go +++ b/contract/vm_multicall.go @@ -305,5 +305,5 @@ var multicall_payload = []byte { 0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c, 0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e, 0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61,0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d, - 0x7d + 0x7d, } diff --git a/contract/vm_test.go b/contract/vm_test.go index 1a8a949dd..36c5986ad 100644 --- a/contract/vm_test.go +++ b/contract/vm_test.go @@ -6261,6 +6261,11 @@ function set(key, value) dict[key] = value end +function inc(key) + dict[key] = (dict[key] or 0) + 1 + contract.event("new_value", dict[key]) +end + function add(value) local key = (last:get() or 0) + 1 dict[tostring(key)] = value @@ -6271,8 +6276,13 @@ function get(key) return dict[key] end -abi.register(add, set, set_name) -abi.register_view(get_dict, get_list, get_table, works, fails, get, get_name, hello) +function sort(list) + table.sort(list) + return list +end + +abi.register(add, set, inc, set_name) +abi.register_view(get_dict, get_list, get_table, works, fails, get, get_name, sort, hello) function call(...) return contract.call(...) @@ -6341,8 +6351,8 @@ abi.payable(recv_aergo) ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], ["store","array"], ["remove","%array%",3], - ["return","%array%"] - ]`, ``, `["first","second",123,12.5,true]`) + ["return","%array%","%last_result%"] + ]`, ``, `[["first","second",123,12.5,true],"third"]`) // create new dict or array using fromjson @@ -6386,6 +6396,39 @@ abi.payable(recv_aergo) ]`, ``, `["one",22,3.3,true,false]`) + // get_size + + multicall(t, bc, "ac1", `[ + ["let","str","this is a string"], + ["get_size","%str%"], + ["return","%last_result%"] + ]`, ``, `16`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["get_size","%list%"], + ["return","%last_result%"] + ]`, ``, `7`) + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_size","%obj%"], + ["return","%last_result%"] + ]`, ``, `0`) + + + // get_keys + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_keys","%obj%"], + ["store","keys"], + ["get_size","%keys%"], + ["return","%last_result%","%keys%"] + ]`, ``, `[3,["one","three","two"]]`) + + + // BIGNUM @@ -6841,32 +6884,48 @@ abi.payable(recv_aergo) ]`, ``, `"130000000000000000003"`) - // FOR "BREAK" + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `99`) + multicall(t, bc, "ac1", `[ - ["let","c",0], - ["for","n",1,10], - ["add","%c%",1], - ["store","c"], - ["if","%n%","=",5], - ["let","n",500], - ["end"], + ["tonumber","0"], + ["for","n",5,1,-1], + ["add","%last_result%",1], ["loop"], - ["return","%c%"] + ["return","%last_result%"] ]`, ``, `5`) multicall(t, bc, "ac1", `[ ["tonumber","0"], - ["let","c",0], - ["for","n",1,10], + ["for","n",5,1], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `0`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5], ["add","%last_result%",1], - ["if","%n%","=",5], - ["let","n",500], - ["end"], ["loop"], ["return","%last_result%"] ]`, ``, `5`) + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5,-1], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `0`) + + // FOREACH @@ -6880,6 +6939,36 @@ abi.payable(recv_aergo) ["return","%r%"] ]`, ``, `66`) + multicall(t, bc, "ac1", `[ + ["let","list",[11,22,33]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `3`) + + multicall(t, bc, "ac1", `[ + ["let","list",[]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `0`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `7`) + multicall(t, bc, "ac1", `[ ["let","list",[10,21,32]], ["let","r",0], @@ -6893,6 +6982,209 @@ abi.payable(recv_aergo) ]`, ``, `31`) + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_keys","%obj%"], + ["foreach","key","%last_result%"], + ["concat","%str%","%key%"], + ["store","str"], + ["loop"], + ["return","%str%"] + ]`, ``, `"onethreetwo"`) + + + + // FORPAIR + + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","sum",0], + ["let","obj",{"one":1,"two":2,"three":3}], + ["forpair","key","value","%obj%"], + ["concat","%str%","%key%"], + ["store","str"], + ["add","%sum%","%value%"], + ["store","sum"], + ["loop"], + ["return","%str%","%sum%"] + ]`, ``, `["onethreetwo",6]`) + + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","sum",0], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["concat","%str%","%key%"], + ["store","str"], + ["add","%sum%","%value%"], + ["store","sum"], + ["loop"], + ["return","%str%","%sum%"] + ]`, ``, `["fouronethreetwo",12]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","values",[]], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["insert","%names%","%key%"], + ["insert","%values%","%value%"], + ["loop"], + ["return","%names%","%values%"] + ]`, ``, `[["four","one","three","two"],[4.5,1.5,3.5,2.5]]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","values",[]], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["insert","%names%","%key%"], + ["insert","%values%","%value%"], + ["loop"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","sort","%values%"], + ["store","values"], + ["return","%names%","%values%"] + ]`, ``, `[["four","one","three","two"],[1.5,2.5,3.5,4.5]]`) + + multicall(t, bc, "ac1", `[ + ["let","obj",{}], + ["let","counter",0], + ["forpair","key","value","%obj%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `0`) + + + + // FOR "BREAK" + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["if","%n%","=",5], + ["let","n",500], + ["end"], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["if","%n%","=",475], + ["let","n",2], + ["end"], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["if","%n%","=",5], + ["break"], + ["end"], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["break","if","%n%","=",5], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["if","%n%","=",475], + ["break"], + ["end"], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["break","if","%n%","=",475], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["loop"], + ["return","%n%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["break"], + ["loop"], + ["return","%n%"] + ]`, ``, `1`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","list",["one","two","three","four"]], + ["foreach","item","%list%"], + ["if","%item%","=","three"], + ["break"], + ["end"], + ["insert","%names%","%item%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["one","two"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","list",["one","two","three","four"]], + ["foreach","item","%list%"], + ["break","if","%item%","=","three"], + ["insert","%names%","%item%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["one","two"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","obj",{"one":true,"two":false,"three":false,"four":true}], + ["forpair","key","value","%obj%"], + ["if","%value%","=",false], + ["break"], + ["end"], + ["insert","%names%","%key%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["four","one"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","obj",{"one":true,"two":false,"three":false,"four":true}], + ["forpair","key","value","%obj%"], + ["break","if","%value%","=",false], + ["insert","%names%","%key%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["four","one"]`) + + + // RETURN before the end multicall(t, bc, "ac1", `[ @@ -6915,6 +7207,21 @@ abi.payable(recv_aergo) + // FULL LOOPS + + multicall(t, bc, "ac1", `[ + ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], + ["call","%c%","inc","n"], + ["call","%c%","get","n"], + ["if","%last_result%",">=",5], + ["return","%last_result%"], + ["end"], + ["loop"] + ]`, ``, `5`) + + + + // CALLS multicall(t, bc, "ac1", `[ @@ -7113,7 +7420,7 @@ abi.payable(recv_aergo) - // aergo balance and send + // aergo BALANCE and SEND multicall(t, bc, "ac5", `[ ["balance"], From a3e3ca488f63c27f06db239fd779144ebccdb930 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Mon, 15 Aug 2022 15:36:39 -0300 Subject: [PATCH 09/49] [contract] fix error messages on multicall code --- contract/vm.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contract/vm.go b/contract/vm.go index 50d90747f..ed1751f36 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -1386,7 +1386,11 @@ func vmAutoload(L *LState, funcName string) bool { func (ce *executor) vmLoadCode(id []byte) { var chunkId *C.char if HardforkConfig.IsV3Fork(ce.ctx.blockInfo.No) { - chunkId = C.CString("@" + types.EncodeAddress(id)) + if ce.ctx.isMultiCall { + chunkId = C.CString("@multicall") + } else { + chunkId = C.CString("@" + types.EncodeAddress(id)) + } } else { chunkId = C.CString(hex.EncodeToString(id)) } From cb4344a58c1a70e5e1d1e8cf3df6eb4f65cc2de6 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Tue, 16 Aug 2022 02:59:29 -0300 Subject: [PATCH 10/49] [chain] fix recipient handling for multicall --- chain/chainhandle.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/chain/chainhandle.go b/chain/chainhandle.go index 47010d0ee..fd64b145d 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -921,9 +921,7 @@ func executeTx( isMultiCall := (txBody.Type == types.TxType_MULTICALL) - if isMultiCall { - recipient = account - } else { + if !isMultiCall { if recipient, err = name.Resolve(bs, txBody.Recipient, isQuirkTx); err != nil { return err } @@ -932,7 +930,7 @@ func executeTx( var receiver *state.V status := "SUCCESS" if isMultiCall { - receiver = sender + // no receiver } else if len(recipient) > 0 { receiver, err = bs.GetAccountStateV(recipient) if receiver != nil && txBody.Type == types.TxType_REDEPLOY { From fb5c39ec1f665d6b6e6e0508c09340f1e674a8c5 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 25 Nov 2023 15:30:58 +0000 Subject: [PATCH 11/49] fix build --- cmd/brick/exec/multicall.go | 8 ++++---- contract/contract.go | 2 +- contract/vm.go | 6 +++++- contract/vm_dummy/vm_dummy.go | 10 +++++----- contract/vm_dummy/vm_dummy_test.go | 20 ++++++++++---------- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/cmd/brick/exec/multicall.go b/cmd/brick/exec/multicall.go index d3d1a00f6..bd7a626e9 100644 --- a/cmd/brick/exec/multicall.go +++ b/cmd/brick/exec/multicall.go @@ -5,9 +5,9 @@ import ( "github.com/rs/zerolog" - "github.com/aergoio/aergo/cmd/brick/context" - "github.com/aergoio/aergo/contract" - "github.com/aergoio/aergo/types" + "github.com/aergoio/aergo/v2/cmd/brick/context" + "github.com/aergoio/aergo/v2/contract/vm_dummy" + "github.com/aergoio/aergo/v2/types" ) func init() { @@ -76,7 +76,7 @@ func (c *multicall) Run(args string) (string, uint64, []*types.Event, error) { accountName, payload, expectedError, expectedRes, _ := c.parse(args) - multicallTx := contract.NewLuaTxMultiCall(accountName, payload) + multicallTx := vm_dummy.NewLuaTxMultiCall(accountName, payload) logLevel := zerolog.GlobalLevel() diff --git a/contract/contract.go b/contract/contract.go index a0a8722da..9bca46650 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -309,7 +309,7 @@ func preloadWorker() { // check if the tx is valid and if the code should be executed func checkExecution(txType types.TxType, amount *big.Int, payloadSize int, version int32, isDeploy, isContract bool) (do_execute bool, err error) { - if txBody.Type == types.TxType_MULTICALL { + if txType == types.TxType_MULTICALL { return true, nil } diff --git a/contract/vm.go b/contract/vm.go index c7b420bc8..908e915ce 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -180,7 +180,7 @@ func getTraceFile(blkno uint64, tx []byte) *os.File { return f } -func NewVmContext(execCtx context.Context, blockState *state.BlockState, cdb ChainAccessor, sender, reciever *state.V, contractState *state.ContractState, senderID, txHash []byte, bi *types.BlockHeaderInfo, node string, confirmed, query bool, rp uint64, service int, amount *big.Int, gasLimit uint64, feeDelegation bool, isMultiCall bool) *vmContext { +func NewVmContext(execCtx context.Context, blockState *state.BlockState, cdb ChainAccessor, sender, receiver *state.V, contractState *state.ContractState, senderID, txHash []byte, bi *types.BlockHeaderInfo, node string, confirmed, query bool, rp uint64, service int, amount *big.Int, gasLimit uint64, feeDelegation bool, isMultiCall bool) *vmContext { cs := &callState{ctrState: contractState, curState: receiver.State()} @@ -240,6 +240,10 @@ func NewVmContextQuery( return ctx, nil } +func (ctx *vmContext) IsMultiCall() bool { + return ctx.isMultiCall +} + func (ctx *vmContext) IsGasSystem() bool { return fee.GasEnabled(ctx.blockInfo.ForkVersion) && !ctx.isQuery } diff --git a/contract/vm_dummy/vm_dummy.go b/contract/vm_dummy/vm_dummy.go index 2fa95b250..baed5779b 100644 --- a/contract/vm_dummy/vm_dummy.go +++ b/contract/vm_dummy/vm_dummy.go @@ -612,13 +612,13 @@ func NewLuaTxCallFeeDelegate(sender, recipient string, amount uint64, payload st } } -func NewLuaTxMultiCall(sender, code string) *luaTxCall { +func NewLuaTxMultiCall(sender, payload string) *luaTxCall { return &luaTxCall{ luaTxContractCommon: luaTxContractCommon{ - _sender: strHash(sender), - _contract: strHash(""), + _sender: contract.StrHash(sender), + _recipient: contract.StrHash(""), _amount: new(big.Int).SetUint64(0), - _code: []byte(code), + _payload: []byte(payload), txId: newTxId(), multiCall: true, }, @@ -641,7 +641,7 @@ func (l *luaTxCall) run(execCtx context.Context, bs *state.BlockState, bc *Dummy return "", nil, ctrFee, err } - if !ctx.isMultiCall { + if !ctx.IsMultiCall() { err = bs.StageContractState(eContractState) if err != nil { return "", nil, ctrFee, err diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index 6d5e7804a..0aa942f53 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -4547,16 +4547,16 @@ abi.payable(recv_aergo) ` err = bc.ConnectBlock( - NewLuaTxAccount("ac0", 10000000000000000000), - NewLuaTxAccount("ac1", 10000000000000000000), - NewLuaTxAccount("ac2", 10000000000000000000), - NewLuaTxAccount("ac3", 10000000000000000000), - NewLuaTxAccount("ac4", 10000000000000000000), - NewLuaTxAccount("ac5", 10000000000000000000), - NewLuaTxDef("ac0", "tables", 0, definition), - NewLuaTxDef("ac0", "c1", 0, definition), - NewLuaTxDef("ac0", "c2", 0, definition), - NewLuaTxDef("ac0", "c3", 0, definition), + NewLuaTxAccount("ac0", 100, types.Aergo), + NewLuaTxAccount("ac1", 100, types.Aergo), + NewLuaTxAccount("ac2", 100, types.Aergo), + NewLuaTxAccount("ac3", 100, types.Aergo), + NewLuaTxAccount("ac4", 100, types.Aergo), + NewLuaTxAccount("ac5", 100, types.Aergo), + NewLuaTxDeploy("ac0", "tables", 0, definition), + NewLuaTxDeploy("ac0", "c1", 0, definition), + NewLuaTxDeploy("ac0", "c2", 0, definition), + NewLuaTxDeploy("ac0", "c3", 0, definition), ) if err != nil { t.Error(err) From b27419da90998f9e4d4c07992327772297cb68ee Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 25 Nov 2023 15:47:44 +0000 Subject: [PATCH 12/49] use separate lua test file --- .../vm_dummy/test_files/feature_multicall.lua | 90 ++++++++++++++ contract/vm_dummy/vm_dummy_test.go | 111 ++---------------- 2 files changed, 103 insertions(+), 98 deletions(-) create mode 100644 contract/vm_dummy/test_files/feature_multicall.lua diff --git a/contract/vm_dummy/test_files/feature_multicall.lua b/contract/vm_dummy/test_files/feature_multicall.lua new file mode 100644 index 000000000..8dcdfcffa --- /dev/null +++ b/contract/vm_dummy/test_files/feature_multicall.lua @@ -0,0 +1,90 @@ +state.var { + name = state.value(), + last = state.value(), + dict = state.map() +} + +function get_dict() + return {one = 1, two = 2, three = 3} +end + +function get_list() + return {'first', 'second', 'third', 123, 12.5, true} +end + +function get_table() + return { name = "Test", second = 'Te"st', number = 123, bool = true, array = {11,22,33} } +end + +function works() + return 123 +end + +function fails() + assert(false, "this call should fail") +end + +function hello(name) + return 'hello ' .. name +end + +function set_name(val) + name:set(val) + assert(type(val)=='string', "must be string") +end + +function get_name() + return name:get() +end + +function set(key, value) + dict[key] = value +end + +function inc(key) + dict[key] = (dict[key] or 0) + 1 + contract.event("new_value", dict[key]) +end + +function add(value) + local key = (last:get() or 0) + 1 + dict[tostring(key)] = value + last:set(key) +end + +function get(key) + return dict[key] +end + +function sort(list) + table.sort(list) + return list +end + +abi.register(add, set, inc, set_name) +abi.register_view(get_dict, get_list, get_table, works, fails, get, get_name, sort, hello) + +function call(...) + return contract.call(...) +end + +function is_contract(address) + return system.isContract(address) +end + +function sender() + return system.getSender() +end + +function origin() + return system.getOrigin() +end + +abi.register(call) +abi.register_view(is_contract, sender, origin) + +function recv_aergo() + -- does nothing +end + +abi.payable(recv_aergo) diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index 0aa942f53..aed1748ea 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -4397,6 +4397,8 @@ func TestContractIsolation(t *testing.T) { ////////////////////////////////////////////////////////////////////// func multicall(t *testing.T, bc *DummyChain, params ...string) { + t.Helper() + var expectedError, expectedResult string account := params[0] payload := params[1] @@ -4412,6 +4414,7 @@ func multicall(t *testing.T, bc *DummyChain, params ...string) { err := bc.ConnectBlock(tx) if err != nil { t.Error(err) + return } if expectedError == "" && expectedResult != "" { @@ -4428,6 +4431,8 @@ func call(t *testing.T, bc *DummyChain, contract string, function string, args string, expectedError string, expectedResult string) { + t.Helper() + callinfo := fmt.Sprintf(`{"Name":"%s", "Args":%s}`, function, args) tx := NewLuaTxCall(account, contract, amount, callinfo).Fail(expectedError) @@ -4435,6 +4440,7 @@ func call(t *testing.T, bc *DummyChain, err := bc.ConnectBlock(tx) if err != nil { t.Error(err) + return } if expectedError == "" && expectedResult != "" { @@ -4447,105 +4453,14 @@ func call(t *testing.T, bc *DummyChain, } func TestComposableTransactions(t *testing.T) { - bc, err := LoadDummyChain() + code := readLuaCode(t, "feature_multicall.lua") + + bc, err := LoadDummyChain(SetHardForkVersion(3)) if err != nil { t.Errorf("failed to create test database: %v", err) } defer bc.Release() - definition := ` -state.var { - name = state.value(), - last = state.value(), - dict = state.map() -} - -function get_dict() - return {one = 1, two = 2, three = 3} -end - -function get_list() - return {'first', 'second', 'third', 123, 12.5, true} -end - -function get_table() - return { name = "Test", second = 'Te"st', number = 123, bool = true, array = {11,22,33} } -end - -function works() - return 123 -end - -function fails() - assert(false, "this call should fail") -end - -function hello(name) - return 'hello ' .. name -end - -function set_name(val) - name:set(val) - assert(type(val)=='string', "must be string") -end - -function get_name() - return name:get() -end - -function set(key, value) - dict[key] = value -end - -function inc(key) - dict[key] = (dict[key] or 0) + 1 - contract.event("new_value", dict[key]) -end - -function add(value) - local key = (last:get() or 0) + 1 - dict[tostring(key)] = value - last:set(key) -end - -function get(key) - return dict[key] -end - -function sort(list) - table.sort(list) - return list -end - -abi.register(add, set, inc, set_name) -abi.register_view(get_dict, get_list, get_table, works, fails, get, get_name, sort, hello) - -function call(...) - return contract.call(...) -end - -function is_contract(address) - return system.isContract(address) -end - -function sender() - return system.getSender() -end - -function origin() - return system.getOrigin() -end - -abi.register(call) -abi.register_view(is_contract, sender, origin) - -function recv_aergo() - -- does nothing -end - -abi.payable(recv_aergo) -` - err = bc.ConnectBlock( NewLuaTxAccount("ac0", 100, types.Aergo), NewLuaTxAccount("ac1", 100, types.Aergo), @@ -4553,10 +4468,10 @@ abi.payable(recv_aergo) NewLuaTxAccount("ac3", 100, types.Aergo), NewLuaTxAccount("ac4", 100, types.Aergo), NewLuaTxAccount("ac5", 100, types.Aergo), - NewLuaTxDeploy("ac0", "tables", 0, definition), - NewLuaTxDeploy("ac0", "c1", 0, definition), - NewLuaTxDeploy("ac0", "c2", 0, definition), - NewLuaTxDeploy("ac0", "c3", 0, definition), + NewLuaTxDeploy("ac0", "tables", 0, code), + NewLuaTxDeploy("ac0", "c1", 0, code), + NewLuaTxDeploy("ac0", "c2", 0, code), + NewLuaTxDeploy("ac0", "c3", 0, code), ) if err != nil { t.Error(err) From 54e792a31cda8f1cafb23a982e01e883503b7a3e Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 25 Nov 2023 17:02:17 +0000 Subject: [PATCH 13/49] fix test --- contract/vm_dummy/vm_dummy_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index aed1748ea..8eddd5b98 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -4462,12 +4462,12 @@ func TestComposableTransactions(t *testing.T) { defer bc.Release() err = bc.ConnectBlock( - NewLuaTxAccount("ac0", 100, types.Aergo), - NewLuaTxAccount("ac1", 100, types.Aergo), - NewLuaTxAccount("ac2", 100, types.Aergo), - NewLuaTxAccount("ac3", 100, types.Aergo), - NewLuaTxAccount("ac4", 100, types.Aergo), - NewLuaTxAccount("ac5", 100, types.Aergo), + NewLuaTxAccount("ac0", 10, types.Aergo), + NewLuaTxAccount("ac1", 10, types.Aergo), + NewLuaTxAccount("ac2", 10, types.Aergo), + NewLuaTxAccount("ac3", 10, types.Aergo), + NewLuaTxAccount("ac4", 10, types.Aergo), + NewLuaTxAccount("ac5", 10, types.Aergo), NewLuaTxDeploy("ac0", "tables", 0, code), NewLuaTxDeploy("ac0", "c1", 0, code), NewLuaTxDeploy("ac0", "c2", 0, code), From cd2700fb52fa3f085c717500c51a417f3a66bdaa Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 25 Nov 2023 19:25:39 +0000 Subject: [PATCH 14/49] update test --- contract/vm_dummy/vm_dummy_test.go | 2417 ++++++++++++++-------------- 1 file changed, 1209 insertions(+), 1208 deletions(-) diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index bab242cba..cee29ffd7 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -22,6 +22,8 @@ import ( const min_version int32 = 2 const max_version int32 = 4 +const min_version_multicall int32 = 4 + func TestMaxCallDepth(t *testing.T) { //code := readLuaCode(t, "maxcalldepth_1.lua") // this contract receives a list of contract IDs to be called @@ -4397,32 +4399,32 @@ func TestContractIsolation(t *testing.T) { ////////////////////////////////////////////////////////////////////// func multicall(t *testing.T, bc *DummyChain, params ...string) { - t.Helper() - - var expectedError, expectedResult string - account := params[0] - payload := params[1] - if len(params) > 2 { - expectedError = params[2] - } - if len(params) > 3 { - expectedResult = params[3] - } - - tx := NewLuaTxMultiCall(account, payload).Fail(expectedError) - - err := bc.ConnectBlock(tx) - if err != nil { - t.Error(err) - return - } - - if expectedError == "" && expectedResult != "" { - receipt := bc.GetReceipt(tx.Hash()) - if receipt.GetRet() != expectedResult { - t.Errorf("multicall invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) - } - } + t.Helper() + + var expectedError, expectedResult string + account := params[0] + payload := params[1] + if len(params) > 2 { + expectedError = params[2] + } + if len(params) > 3 { + expectedResult = params[3] + } + + tx := NewLuaTxMultiCall(account, payload).Fail(expectedError) + + err := bc.ConnectBlock(tx) + if err != nil { + t.Error(err) + return + } + + if expectedError == "" && expectedResult != "" { + receipt := bc.GetReceipt(tx.Hash()) + if receipt.GetRet() != expectedResult { + t.Errorf("multicall invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) + } + } } @@ -4431,1252 +4433,1251 @@ func call(t *testing.T, bc *DummyChain, contract string, function string, args string, expectedError string, expectedResult string) { - t.Helper() + t.Helper() - callinfo := fmt.Sprintf(`{"Name":"%s", "Args":%s}`, function, args) + callinfo := fmt.Sprintf(`{"Name":"%s", "Args":%s}`, function, args) - tx := NewLuaTxCall(account, contract, amount, callinfo).Fail(expectedError) + tx := NewLuaTxCall(account, contract, amount, callinfo).Fail(expectedError) - err := bc.ConnectBlock(tx) - if err != nil { - t.Error(err) - return - } + err := bc.ConnectBlock(tx) + if err != nil { + t.Error(err) + return + } - if expectedError == "" && expectedResult != "" { - receipt := bc.GetReceipt(tx.Hash()) - if receipt.GetRet() != expectedResult { - t.Errorf("call invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) - } - } + if expectedError == "" && expectedResult != "" { + receipt := bc.GetReceipt(tx.Hash()) + if receipt.GetRet() != expectedResult { + t.Errorf("call invalid result - expected: %s got: %s", expectedResult, receipt.GetRet()) + } + } } func TestComposableTransactions(t *testing.T) { - code := readLuaCode(t, "feature_multicall.lua") - - bc, err := LoadDummyChain(SetHardForkVersion(3)) - if err != nil { - t.Errorf("failed to create test database: %v", err) - } - defer bc.Release() - - err = bc.ConnectBlock( - NewLuaTxAccount("ac0", 10, types.Aergo), - NewLuaTxAccount("ac1", 10, types.Aergo), - NewLuaTxAccount("ac2", 10, types.Aergo), - NewLuaTxAccount("ac3", 10, types.Aergo), - NewLuaTxAccount("ac4", 10, types.Aergo), - NewLuaTxAccount("ac5", 10, types.Aergo), - NewLuaTxDeploy("ac0", "tables", 0, code), - NewLuaTxDeploy("ac0", "c1", 0, code), - NewLuaTxDeploy("ac0", "c2", 0, code), - NewLuaTxDeploy("ac0", "c3", 0, code), - ) - if err != nil { - t.Error(err) - } - - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_dict"], - ["store","dict"], - ["set","%dict%","two",22], - ["set","%dict%","four",4], - ["set","%dict%","one",null], - ["get","%dict%","two"], - ["set","%dict%","copy","%last_result%"], - ["return","%dict%"] - ]`, ``, `{"copy":22,"four":4,"three":3,"two":22}`) - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], - ["store","array"], - ["set","%array%",2,"2nd"], - ["insert","%array%",1,"zero"], - ["insert","%array%","last"], - ["return","%array%"] - ]`, ``, `["zero","first","2nd","third",123,12.5,true,"last"]`) - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], - ["store","array"], - ["remove","%array%",3], - ["return","%array%","%last_result%"] - ]`, ``, `[["first","second",123,12.5,true],"third"]`) - - - // create new dict or array using fromjson - - multicall(t, bc, "ac1", `[ - ["fromjson","{\"one\":1,\"two\":2}"], - ["set","%last_result%","three",3], - ["return","%last_result%"] - ]`, ``, `{"one":1,"three":3,"two":2}`) - - - // define dict or list using let - - multicall(t, bc, "ac1", `[ - ["let","obj",{"one":1,"two":2}], - ["set","%obj%","three",3], - ["return","%obj%"] - ]`, ``, `{"one":1,"three":3,"two":2}`) - - multicall(t, bc, "ac1", `[ - ["let","list",["one",1,"two",2,2.5,true,false]], - ["set","%list%",4,"three"], - ["insert","%list%",1,"first"], - ["insert","%list%","last"], - ["return","%list%"] - ]`, ``, `["first","one",1,"two","three",2.5,true,false,"last"]`) - - multicall(t, bc, "ac1", `[ - ["let","list",["one",22,3.3,true,false]], - ["get","%list%",1], - ["assert","%last_result%","=","one"], - ["get","%list%",2], - ["assert","%last_result%","=",22], - ["get","%list%",3], - ["assert","%last_result%","=",3.3], - ["get","%list%",4], - ["assert","%last_result%","=",true], - ["get","%list%",5], - ["assert","%last_result%","=",false], - ["return","%list%"] - ]`, ``, `["one",22,3.3,true,false]`) - - - // get_size - - multicall(t, bc, "ac1", `[ - ["let","str","this is a string"], - ["get_size","%str%"], - ["return","%last_result%"] - ]`, ``, `16`) - - multicall(t, bc, "ac1", `[ - ["let","list",["one",1,"two",2,2.5,true,false]], - ["get_size","%list%"], - ["return","%last_result%"] - ]`, ``, `7`) - - multicall(t, bc, "ac1", `[ - ["let","obj",{"one":1,"two":2,"three":3}], - ["get_size","%obj%"], - ["return","%last_result%"] - ]`, ``, `0`) - - - // get_keys - - multicall(t, bc, "ac1", `[ - ["let","obj",{"one":1,"two":2,"three":3}], - ["get_keys","%obj%"], - ["store","keys"], - ["get_size","%keys%"], - ["return","%last_result%","%keys%"] - ]`, ``, `[3,["one","three","two"]]`) - - - - - // BIGNUM - - multicall(t, bc, "ac1", `[ - ["tobignum",123], - ["store","a"], - ["tobignum",123], - ["store","b"], - ["mul","%a%","%b%"], - ["return","%last_result%"] - ]`, ``, `{"_bignum":"15129"}`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","100000"], - ["store","b"], - ["div","%a%","%b%"], - ["return","%last_result%"] - ]`, ``, `{"_bignum":"5000000000000000"}`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","100000"], - ["store","b"], - ["div","%a%","%b%"], - ["tostring","%last_result%"], - ["return","%last_result%"] - ]`, ``, `"5000000000000000"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - - ["tobignum","100000"], - ["div","%a%","%last_result%"], - ["store","a"], - - ["tobignum","1000000000000000"], - ["sub","%a%","%last_result%"], - ["store","a"], - - ["tobignum","1234"], - ["add","%a%","%last_result%"], - ["store","a"], - - ["tobignum","2"], - ["pow","%a%","%last_result%"], - ["sqrt","%last_result%"], - ["store","a"], - - ["tobignum","2"], - ["mod","%a%","10000"], - - ["return","%last_result%"] - ]`, ``, `{"_bignum":"1234"}`) - - multicall(t, bc, "ac1", `[ - ["let","a",25], - ["sqrt","%a%"], - ["return","%last_result%"] - ]`, ``, `{"_bignum":"5"}`) - - multicall(t, bc, "ac1", `[ - ["let","a",25], - ["pow","%a%",0.5], - ["return","%last_result%"] - ]`, ``, `5`) - - - - // STRINGS - - multicall(t, bc, "ac1", `[ - ["format","%s%s%s","hello"," ","world"], - ["return","%last_result%"] - ]`, ``, `"hello world"`) - - multicall(t, bc, "ac1", `[ - ["let","s","hello world"], - ["substr","%s%",1,4], - ["return","%last_result%"] - ]`, ``, `"hell"`) - - multicall(t, bc, "ac1", `[ - ["let","s","hello world"], - ["substr","%s%",-2,-1], - ["return","%last_result%"] - ]`, ``, `"ld"`) - - multicall(t, bc, "ac1", `[ - ["let","s","the amount is 12345"], - ["find","%s%","%d+"], - ["tonumber","%last_result%"], - ["return","%last_result%"] - ]`, ``, `12345`) - - multicall(t, bc, "ac1", `[ - ["let","s","rate: 55 10%"], - ["find","%s%","(%d+)%%"], - ["tonumber","%last_result%"], - ["return","%last_result%"] - ]`, ``, `10`) - - multicall(t, bc, "ac1", `[ - ["let","s","rate: 12%"], - ["find","%s%","%s*(%d+)%%"], - ["tonumber","%last_result%"], - ["return","%last_result%"] - ]`, ``, `12`) - - multicall(t, bc, "ac1", `[ - ["let","s","hello world"], - ["replace","%s%","hello","good bye"], - ["return","%last_result%"] - ]`, ``, `"good bye world"`) - - multicall(t, bc, "ac1", `[ - ["fromjson","{\"name\":\"ticket\",\"value\":12.5,\"amount\":10}"], - ["replace","name = $name, value = $value, amount = $amount","%$(%w+)","%last_result%"], - ["return","%last_result%"] - ]`, ``, `"name = ticket, value = 12.5, amount = 10"`) - - - // IF THEN ELSE - - multicall(t, bc, "ac1", `[ - ["let","s",20], - ["if","%s%",">=",20], - ["let","b","big"], - ["elif","%s%",">=",10], - ["let","b","medium"], - ["else"], - ["let","b","low"], - ["end"], - ["let","c","after"], - ["return","%b%","%c%"] - ]`, ``, `["big","after"]`) - - multicall(t, bc, "ac1", `[ - ["let","s",10], - ["if","%s%",">=",20], - ["let","b","big"], - ["elif","%s%",">=",10], - ["let","b","medium"], - ["else"], - ["let","b","low"], - ["end"], - ["let","c","after"], - ["return","%b%","%c%"] - ]`, ``, `["medium","after"]`) - - multicall(t, bc, "ac1", `[ - ["let","s",5], - ["if","%s%",">=",20], - ["let","b","big"], - ["elif","%s%",">=",10], - ["let","b","medium"], - ["else"], - ["let","b","low"], - ["end"], - ["let","c","after"], - ["return","%b%","%c%"] - ]`, ``, `["low","after"]`) - - multicall(t, bc, "ac1", `[ - ["let","s",20], - ["if","%s%",">=",20], - ["return","big"], - ["elif","%s%",">=",10], - ["return","medium"], - ["else"], - ["return","low"], - ["end"], - ["return","after"] - ]`, ``, `"big"`) - - multicall(t, bc, "ac1", `[ - ["let","s",10], - ["if","%s%",">=",20], - ["return","big"], - ["elif","%s%",">=",10], - ["return","medium"], - ["else"], - ["return","low"], - ["end"], - ["return","after"] - ]`, ``, `"medium"`) - - multicall(t, bc, "ac1", `[ - ["let","s",5], - ["if","%s%",">=",20], - ["return","big"], - ["elif","%s%",">=",10], - ["return","medium"], - ["else"], - ["return","low"], - ["end"], - ["return","after"] - ]`, ``, `"low"`) - - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000000"], - ["store","b"], - ["if","%a%","=","%b%"], - ["let","b","equal"], - ["else"], - ["let","b","diff"], - ["end"], - ["return","%b%"] - ]`, ``, `"equal"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["if","%a%","=","%b%"], - ["let","b","equal"], - ["else"], - ["let","b","diff"], - ["end"], - ["return","%b%"] - ]`, ``, `"diff"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000001"], - ["store","a"], - ["tobignum","500000000000000000000"], - ["store","b"], - ["if","%a%",">","%b%"], - ["let","b","bigger"], - ["else"], - ["let","b","lower"], - ["end"], - ["return","%b%"] - ]`, ``, `"bigger"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["if","%a%",">","%b%"], - ["let","b","bigger"], - ["else"], - ["let","b","lower"], - ["end"], - ["return","%b%"] - ]`, ``, `"lower"`) - - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["if","%a%","<","%b%","and","1","=","0"], - ["let","b","wrong 1"], - ["elif","%a%","<","%b%","and","1","=","1"], - ["let","b","correct"], - ["else"], - ["let","b","wrong 2"], - ["end"], - ["return","%b%"] - ]`, ``, `"correct"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["if","%a%","<","%b%","and",1,"=",0], - ["let","b","wrong 1"], - ["elif","%a%","<","%b%","and",1,"=",1], - ["let","b","correct"], - ["else"], - ["let","b","wrong 2"], - ["end"], - ["return","%b%"] - ]`, ``, `"correct"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["tobignum","400000000000000000000"], - ["store","c"], - ["if","%a%","<","%b%","and","%a%","<","%c%"], - ["let","b","wrong 1"], - ["elif","%a%",">","%b%","and","%a%",">","%c%"], - ["let","b","wrong 2"], - ["elif","%a%","<","%b%","and","%a%",">","%c%"], - ["let","b","correct"], - ["else"], - ["let","b","wrong 3"], - ["end"], - ["return","%b%"] - ]`, ``, `"correct"`) - - multicall(t, bc, "ac1", `[ - ["tobignum","500000000000000000000"], - ["store","a"], - ["tobignum","500000000000000000001"], - ["store","b"], - ["tobignum","400000000000000000000"], - ["store","c"], - ["tostring",0], - - ["if","%a%",">","%b%","or","%a%","<","%c%"], - ["format","%s%s","%last_result%","1"], - ["end"], - - ["if","%a%","=","%b%","or","%a%","=","%c%"], - ["format","%s%s","%last_result%","2"], - ["end"], - - ["if","%a%","<","%b%","or","%a%","<","%c%"], - ["format","%s%s","%last_result%","3"], - ["end"], - - ["if","%a%",">","%b%","or","%a%",">","%c%"], - ["format","%s%s","%last_result%","4"], - ["end"], - - ["if","%a%","<","%b%","or","%a%",">","%c%"], - ["format","%s%s","%last_result%","5"], - ["end"], - - ["if","%a%","!=","%b%","or","%a%","=","%c%"], - ["format","%s%s","%last_result%","6"], - ["end"], - - ["if","%a%","=","%b%","or","%a%","!=","%c%"], - ["format","%s%s","%last_result%","7"], - ["end"], - - - ["if","%a%",">=","%b%","and","%a%","<=","%c%"], - ["format","%s%s","%last_result%","8"], - ["end"], - - ["if","%a%",">=","%c%","and","%a%","<=","%b%"], - ["format","%s%s","%last_result%","9"], - ["end"], - - ["if","%b%",">=","%a%","and","%b%","<=","%c%"], - ["format","%s%s","%last_result%","A"], - ["end"], - - ["if","%b%",">=","%c%","and","%b%","<=","%a%"], - ["format","%s%s","%last_result%","B"], - ["end"], - - ["if","%c%",">=","%a%","and","%c%","<=","%b%"], - ["format","%s%s","%last_result%","C"], - ["end"], - - ["if","%c%",">=","%b%","and","%c%","<=","%a%"], - ["format","%s%s","%last_result%","D"], - ["end"], - - - ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",0], - ["format","%s%s","%last_result%","E"], - ["end"], - - ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",1], - ["format","%s%s","%last_result%","F"], - ["end"], - - ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",0], - ["format","%s%s","%last_result%","G"], - ["end"], - - ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",1], - ["format","%s%s","%last_result%","H"], - ["end"], - - - ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",0], - ["format","%s%s","%last_result%","I"], - ["end"], - - ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",1], - ["format","%s%s","%last_result%","J"], - ["end"], - - ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",0], - ["format","%s%s","%last_result%","K"], - ["end"], + code := readLuaCode(t, "feature_multicall.lua") - ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",1], - ["format","%s%s","%last_result%","L"], - ["end"], + for version := min_version_multicall; version <= max_version; version++ { + bc, err := LoadDummyChain(SetHardForkVersion(version)) + require.NoErrorf(t, err, "failed to create dummy chain") + defer bc.Release() + err = bc.ConnectBlock( + NewLuaTxAccount("ac0", 10, types.Aergo), + NewLuaTxAccount("ac1", 10, types.Aergo), + NewLuaTxAccount("ac2", 10, types.Aergo), + NewLuaTxAccount("ac3", 10, types.Aergo), + NewLuaTxAccount("ac4", 10, types.Aergo), + NewLuaTxAccount("ac5", 10, types.Aergo), + NewLuaTxDeploy("ac0", "tables", 0, code), + NewLuaTxDeploy("ac0", "c1", 0, code), + NewLuaTxDeploy("ac0", "c2", 0, code), + NewLuaTxDeploy("ac0", "c3", 0, code), + ) + if err != nil { + t.Error(err) + } - ["if",1,"=",0,"or","%a%",">=","%b%","and","%a%","<=","%c%"], - ["format","%s%s","%last_result%","M"], - ["end"], - ["if",1,"=",1,"or","%a%",">=","%b%","and","%a%","<=","%c%"], - ["format","%s%s","%last_result%","N"], - ["end"], + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_dict"], + ["store","dict"], + ["set","%dict%","two",22], + ["set","%dict%","four",4], + ["set","%dict%","one",null], + ["get","%dict%","two"], + ["set","%dict%","copy","%last_result%"], + ["return","%dict%"] + ]`, ``, `{"copy":22,"four":4,"three":3,"two":22}`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], + ["store","array"], + ["set","%array%",2,"2nd"], + ["insert","%array%",1,"zero"], + ["insert","%array%","last"], + ["return","%array%"] + ]`, ``, `["zero","first","2nd","third",123,12.5,true,"last"]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_list"], + ["store","array"], + ["remove","%array%",3], + ["return","%array%","%last_result%"] + ]`, ``, `[["first","second",123,12.5,true],"third"]`) + + + // create new dict or array using fromjson + + multicall(t, bc, "ac1", `[ + ["fromjson","{\"one\":1,\"two\":2}"], + ["set","%last_result%","three",3], + ["return","%last_result%"] + ]`, ``, `{"one":1,"three":3,"two":2}`) + + + // define dict or list using let + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2}], + ["set","%obj%","three",3], + ["return","%obj%"] + ]`, ``, `{"one":1,"three":3,"two":2}`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["set","%list%",4,"three"], + ["insert","%list%",1,"first"], + ["insert","%list%","last"], + ["return","%list%"] + ]`, ``, `["first","one",1,"two","three",2.5,true,false,"last"]`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",22,3.3,true,false]], + ["get","%list%",1], + ["assert","%last_result%","=","one"], + ["get","%list%",2], + ["assert","%last_result%","=",22], + ["get","%list%",3], + ["assert","%last_result%","=",3.3], + ["get","%list%",4], + ["assert","%last_result%","=",true], + ["get","%list%",5], + ["assert","%last_result%","=",false], + ["return","%list%"] + ]`, ``, `["one",22,3.3,true,false]`) + + + // get_size + + multicall(t, bc, "ac1", `[ + ["let","str","this is a string"], + ["get_size","%str%"], + ["return","%last_result%"] + ]`, ``, `16`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["get_size","%list%"], + ["return","%last_result%"] + ]`, ``, `7`) + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_size","%obj%"], + ["return","%last_result%"] + ]`, ``, `0`) + + + // get_keys + + multicall(t, bc, "ac1", `[ + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_keys","%obj%"], + ["store","keys"], + ["get_size","%keys%"], + ["return","%last_result%","%keys%"] + ]`, ``, `[3,["one","three","two"]]`) + + + + + // BIGNUM + + multicall(t, bc, "ac1", `[ + ["tobignum",123], + ["store","a"], + ["tobignum",123], + ["store","b"], + ["mul","%a%","%b%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"15129"}`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","100000"], + ["store","b"], + ["div","%a%","%b%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"5000000000000000"}`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","100000"], + ["store","b"], + ["div","%a%","%b%"], + ["tostring","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"5000000000000000"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + + ["tobignum","100000"], + ["div","%a%","%last_result%"], + ["store","a"], + + ["tobignum","1000000000000000"], + ["sub","%a%","%last_result%"], + ["store","a"], + + ["tobignum","1234"], + ["add","%a%","%last_result%"], + ["store","a"], + + ["tobignum","2"], + ["pow","%a%","%last_result%"], + ["sqrt","%last_result%"], + ["store","a"], + + ["tobignum","2"], + ["mod","%a%","10000"], + + ["return","%last_result%"] + ]`, ``, `{"_bignum":"1234"}`) + + multicall(t, bc, "ac1", `[ + ["let","a",25], + ["sqrt","%a%"], + ["return","%last_result%"] + ]`, ``, `{"_bignum":"5"}`) + + multicall(t, bc, "ac1", `[ + ["let","a",25], + ["pow","%a%",0.5], + ["return","%last_result%"] + ]`, ``, `5`) + + + + // STRINGS + + multicall(t, bc, "ac1", `[ + ["format","%s%s%s","hello"," ","world"], + ["return","%last_result%"] + ]`, ``, `"hello world"`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["substr","%s%",1,4], + ["return","%last_result%"] + ]`, ``, `"hell"`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["substr","%s%",-2,-1], + ["return","%last_result%"] + ]`, ``, `"ld"`) + + multicall(t, bc, "ac1", `[ + ["let","s","the amount is 12345"], + ["find","%s%","%d+"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `12345`) + + multicall(t, bc, "ac1", `[ + ["let","s","rate: 55 10%"], + ["find","%s%","(%d+)%%"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `10`) + + multicall(t, bc, "ac1", `[ + ["let","s","rate: 12%"], + ["find","%s%","%s*(%d+)%%"], + ["tonumber","%last_result%"], + ["return","%last_result%"] + ]`, ``, `12`) + + multicall(t, bc, "ac1", `[ + ["let","s","hello world"], + ["replace","%s%","hello","good bye"], + ["return","%last_result%"] + ]`, ``, `"good bye world"`) + + multicall(t, bc, "ac1", `[ + ["fromjson","{\"name\":\"ticket\",\"value\":12.5,\"amount\":10}"], + ["replace","name = $name, value = $value, amount = $amount","%$(%w+)","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"name = ticket, value = 12.5, amount = 10"`) + + + // IF THEN ELSE + + multicall(t, bc, "ac1", `[ + ["let","s",20], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["big","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",10], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["medium","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",5], + ["if","%s%",">=",20], + ["let","b","big"], + ["elif","%s%",">=",10], + ["let","b","medium"], + ["else"], + ["let","b","low"], + ["end"], + ["let","c","after"], + ["return","%b%","%c%"] + ]`, ``, `["low","after"]`) + + multicall(t, bc, "ac1", `[ + ["let","s",20], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"big"`) + + multicall(t, bc, "ac1", `[ + ["let","s",10], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"medium"`) + + multicall(t, bc, "ac1", `[ + ["let","s",5], + ["if","%s%",">=",20], + ["return","big"], + ["elif","%s%",">=",10], + ["return","medium"], + ["else"], + ["return","low"], + ["end"], + ["return","after"] + ]`, ``, `"low"`) + + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000000"], + ["store","b"], + ["if","%a%","=","%b%"], + ["let","b","equal"], + ["else"], + ["let","b","diff"], + ["end"], + ["return","%b%"] + ]`, ``, `"equal"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","=","%b%"], + ["let","b","equal"], + ["else"], + ["let","b","diff"], + ["end"], + ["return","%b%"] + ]`, ``, `"diff"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000001"], + ["store","a"], + ["tobignum","500000000000000000000"], + ["store","b"], + ["if","%a%",">","%b%"], + ["let","b","bigger"], + ["else"], + ["let","b","lower"], + ["end"], + ["return","%b%"] + ]`, ``, `"bigger"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%",">","%b%"], + ["let","b","bigger"], + ["else"], + ["let","b","lower"], + ["end"], + ["return","%b%"] + ]`, ``, `"lower"`) + + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","<","%b%","and","1","=","0"], + ["let","b","wrong 1"], + ["elif","%a%","<","%b%","and","1","=","1"], + ["let","b","correct"], + ["else"], + ["let","b","wrong 2"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["if","%a%","<","%b%","and",1,"=",0], + ["let","b","wrong 1"], + ["elif","%a%","<","%b%","and",1,"=",1], + ["let","b","correct"], + ["else"], + ["let","b","wrong 2"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["tobignum","400000000000000000000"], + ["store","c"], + ["if","%a%","<","%b%","and","%a%","<","%c%"], + ["let","b","wrong 1"], + ["elif","%a%",">","%b%","and","%a%",">","%c%"], + ["let","b","wrong 2"], + ["elif","%a%","<","%b%","and","%a%",">","%c%"], + ["let","b","correct"], + ["else"], + ["let","b","wrong 3"], + ["end"], + ["return","%b%"] + ]`, ``, `"correct"`) + + multicall(t, bc, "ac1", `[ + ["tobignum","500000000000000000000"], + ["store","a"], + ["tobignum","500000000000000000001"], + ["store","b"], + ["tobignum","400000000000000000000"], + ["store","c"], + ["tostring",0], + + ["if","%a%",">","%b%","or","%a%","<","%c%"], + ["format","%s%s","%last_result%","1"], + ["end"], + + ["if","%a%","=","%b%","or","%a%","=","%c%"], + ["format","%s%s","%last_result%","2"], + ["end"], + + ["if","%a%","<","%b%","or","%a%","<","%c%"], + ["format","%s%s","%last_result%","3"], + ["end"], + + ["if","%a%",">","%b%","or","%a%",">","%c%"], + ["format","%s%s","%last_result%","4"], + ["end"], + + ["if","%a%","<","%b%","or","%a%",">","%c%"], + ["format","%s%s","%last_result%","5"], + ["end"], + + ["if","%a%","!=","%b%","or","%a%","=","%c%"], + ["format","%s%s","%last_result%","6"], + ["end"], + + ["if","%a%","=","%b%","or","%a%","!=","%c%"], + ["format","%s%s","%last_result%","7"], + ["end"], + + + ["if","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","8"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","9"], + ["end"], + + ["if","%b%",">=","%a%","and","%b%","<=","%c%"], + ["format","%s%s","%last_result%","A"], + ["end"], + + ["if","%b%",">=","%c%","and","%b%","<=","%a%"], + ["format","%s%s","%last_result%","B"], + ["end"], + + ["if","%c%",">=","%a%","and","%c%","<=","%b%"], + ["format","%s%s","%last_result%","C"], + ["end"], + + ["if","%c%",">=","%b%","and","%c%","<=","%a%"], + ["format","%s%s","%last_result%","D"], + ["end"], + + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",0], + ["format","%s%s","%last_result%","E"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","or",1,"=",1], + ["format","%s%s","%last_result%","F"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",0], + ["format","%s%s","%last_result%","G"], + ["end"], + + ["if","%a%",">=","%b%","and","%a%","<=","%c%","and",1,"=",1], + ["format","%s%s","%last_result%","H"], + ["end"], + + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",0], + ["format","%s%s","%last_result%","I"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","or",1,"=",1], + ["format","%s%s","%last_result%","J"], + ["end"], + + ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",0], + ["format","%s%s","%last_result%","K"], + ["end"], - ["if",1,"=",0,"or","%a%",">=","%c%","and","%a%","<=","%b%"], - ["format","%s%s","%last_result%","O"], - ["end"], + ["if","%a%",">=","%c%","and","%a%","<=","%b%","and",1,"=",1], + ["format","%s%s","%last_result%","L"], + ["end"], - ["if",1,"=",1,"or","%a%",">=","%c%","and","%a%","<=","%b%"], - ["format","%s%s","%last_result%","P"], - ["end"], + ["if",1,"=",0,"or","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","M"], + ["end"], - ["return","%last_result%"] - ]`, ``, `"0345679IJLNOP"`) + ["if",1,"=",1,"or","%a%",">=","%b%","and","%a%","<=","%c%"], + ["format","%s%s","%last_result%","N"], + ["end"], + ["if",1,"=",0,"or","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","O"], + ["end"], + ["if",1,"=",1,"or","%a%",">=","%c%","and","%a%","<=","%b%"], + ["format","%s%s","%last_result%","P"], + ["end"], - // FOR - - multicall(t, bc, "ac1", `[ - ["for","n",1,5], - ["loop"], - ["return","%n%"] - ]`, ``, `6`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",1,5], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["tobignum","10000000000000000001"], - ["store","to_add"], - ["tobignum","100000000000000000000"], - - ["for","n",1,3], - ["add","%last_result%","%to_add%"], - ["loop"], - - ["tostring","%last_result%"], - ["return","%last_result%"] - ]`, ``, `"130000000000000000003"`) - - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",500,10,-5], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `99`) - - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",5,1,-1], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",5,1], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `0`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",1,5], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",1,5,-1], - ["add","%last_result%",1], - ["loop"], - ["return","%last_result%"] - ]`, ``, `0`) - - - - // FOREACH - - multicall(t, bc, "ac1", `[ - ["let","list",[11,22,33]], - ["let","r",0], - ["foreach","item","%list%"], - ["add","%r%","%item%"], - ["store","r"], - ["loop"], - ["return","%r%"] - ]`, ``, `66`) - - multicall(t, bc, "ac1", `[ - ["let","list",[11,22,33]], - ["let","counter",0], - ["foreach","item","%list%"], - ["add","%counter%",1], - ["store","counter"], - ["loop"], - ["return","%counter%"] - ]`, ``, `3`) - - multicall(t, bc, "ac1", `[ - ["let","list",[]], - ["let","counter",0], - ["foreach","item","%list%"], - ["add","%counter%",1], - ["store","counter"], - ["loop"], - ["return","%counter%"] - ]`, ``, `0`) - - multicall(t, bc, "ac1", `[ - ["let","list",["one",1,"two",2,2.5,true,false]], - ["let","counter",0], - ["foreach","item","%list%"], - ["add","%counter%",1], - ["store","counter"], - ["loop"], - ["return","%counter%"] - ]`, ``, `7`) - - multicall(t, bc, "ac1", `[ - ["let","list",[10,21,32]], - ["let","r",0], - ["foreach","item","%list%"], - ["if","%item%","<",30], - ["add","%r%","%item%"], - ["store","r"], - ["end"], - ["loop"], - ["return","%r%"] - ]`, ``, `31`) - - - multicall(t, bc, "ac1", `[ - ["let","str",""], - ["let","obj",{"one":1,"two":2,"three":3}], - ["get_keys","%obj%"], - ["foreach","key","%last_result%"], - ["concat","%str%","%key%"], - ["store","str"], - ["loop"], - ["return","%str%"] - ]`, ``, `"onethreetwo"`) - - - - // FORPAIR - - multicall(t, bc, "ac1", `[ - ["let","str",""], - ["let","sum",0], - ["let","obj",{"one":1,"two":2,"three":3}], - ["forpair","key","value","%obj%"], - ["concat","%str%","%key%"], - ["store","str"], - ["add","%sum%","%value%"], - ["store","sum"], - ["loop"], - ["return","%str%","%sum%"] - ]`, ``, `["onethreetwo",6]`) - - multicall(t, bc, "ac1", `[ - ["let","str",""], - ["let","sum",0], - ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], - ["forpair","key","value","%obj%"], - ["concat","%str%","%key%"], - ["store","str"], - ["add","%sum%","%value%"], - ["store","sum"], - ["loop"], - ["return","%str%","%sum%"] - ]`, ``, `["fouronethreetwo",12]`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","values",[]], - ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], - ["forpair","key","value","%obj%"], - ["insert","%names%","%key%"], - ["insert","%values%","%value%"], - ["loop"], - ["return","%names%","%values%"] - ]`, ``, `[["four","one","three","two"],[4.5,1.5,3.5,2.5]]`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","values",[]], - ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], - ["forpair","key","value","%obj%"], - ["insert","%names%","%key%"], - ["insert","%values%","%value%"], - ["loop"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","sort","%values%"], - ["store","values"], - ["return","%names%","%values%"] - ]`, ``, `[["four","one","three","two"],[1.5,2.5,3.5,4.5]]`) - - multicall(t, bc, "ac1", `[ - ["let","obj",{}], - ["let","counter",0], - ["forpair","key","value","%obj%"], - ["add","%counter%",1], - ["store","counter"], - ["loop"], - ["return","%counter%"] - ]`, ``, `0`) - - - - // FOR "BREAK" - - multicall(t, bc, "ac1", `[ - ["let","c",0], - ["for","n",1,10], - ["add","%c%",1], - ["store","c"], - ["if","%n%","=",5], - ["let","n",500], - ["end"], - ["loop"], - ["return","%c%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",500,10,-5], - ["add","%last_result%",1], - ["if","%n%","=",475], - ["let","n",2], - ["end"], - ["loop"], - ["return","%last_result%"] - ]`, ``, `6`) - - multicall(t, bc, "ac1", `[ - ["let","c",0], - ["for","n",1,10], - ["add","%c%",1], - ["store","c"], - ["if","%n%","=",5], - ["break"], - ["end"], - ["loop"], - ["return","%c%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["let","c",0], - ["for","n",1,10], - ["add","%c%",1], - ["store","c"], - ["break","if","%n%","=",5], - ["loop"], - ["return","%c%"] - ]`, ``, `5`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",500,10,-5], - ["add","%last_result%",1], - ["if","%n%","=",475], - ["break"], - ["end"], - ["loop"], - ["return","%last_result%"] - ]`, ``, `6`) - - multicall(t, bc, "ac1", `[ - ["tonumber","0"], - ["for","n",500,10,-5], - ["add","%last_result%",1], - ["break","if","%n%","=",475], - ["loop"], - ["return","%last_result%"] - ]`, ``, `6`) - - multicall(t, bc, "ac1", `[ - ["for","n",1,5], - ["loop"], - ["return","%n%"] - ]`, ``, `6`) - - multicall(t, bc, "ac1", `[ - ["for","n",1,5], - ["break"], - ["loop"], - ["return","%n%"] - ]`, ``, `1`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","list",["one","two","three","four"]], - ["foreach","item","%list%"], - ["if","%item%","=","three"], - ["break"], - ["end"], - ["insert","%names%","%item%"], - ["loop"], - ["return","%names%"] - ]`, ``, `["one","two"]`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","list",["one","two","three","four"]], - ["foreach","item","%list%"], - ["break","if","%item%","=","three"], - ["insert","%names%","%item%"], - ["loop"], - ["return","%names%"] - ]`, ``, `["one","two"]`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","obj",{"one":true,"two":false,"three":false,"four":true}], - ["forpair","key","value","%obj%"], - ["if","%value%","=",false], - ["break"], - ["end"], - ["insert","%names%","%key%"], - ["loop"], - ["return","%names%"] - ]`, ``, `["four","one"]`) - - multicall(t, bc, "ac1", `[ - ["let","names",[]], - ["let","obj",{"one":true,"two":false,"three":false,"four":true}], - ["forpair","key","value","%obj%"], - ["break","if","%value%","=",false], - ["insert","%names%","%key%"], - ["loop"], - ["return","%names%"] - ]`, ``, `["four","one"]`) - - - - // RETURN before the end - - multicall(t, bc, "ac1", `[ - ["let","v",123], - ["if","%v%",">",100], - ["return"], - ["end"], - ["let","v",500], - ["return","%v%"] - ]`, ``, ``) - - multicall(t, bc, "ac1", `[ - ["let","v",123], - ["if","%v%",">",200], - ["return"], - ["end"], - ["let","v",500], - ["return","%v%"] - ]`, ``, `500`) - - - - // FULL LOOPS - - multicall(t, bc, "ac1", `[ - ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], - ["call","%c%","inc","n"], - ["call","%c%","get","n"], - ["if","%last_result%",">=",5], - ["return","%last_result%"], - ["end"], - ["loop"] - ]`, ``, `5`) - - - - - // CALLS - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], - ["assert","%last_result%","=",123], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], - ["return","%last_result%"] - ]`, ``, `123`) - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"] - ]`, `this call should fail`) - - - multicall(t, bc, "ac3", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","test"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], - ["assert","%last_result%","=","test"] - ]`) - - multicall(t, bc, "ac3", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","wrong"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], - ["assert","%last_result%","=","wrong"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",123] - ]`, `must be string`) - - multicall(t, bc, "ac3", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], - ["assert","%last_result%","=","test"], - ["return","%last_result%"] - ]`, ``, `"test"`) - - - multicall(t, bc, "ac3", `[ - ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], - ["call","%c%","set_name","test2"], - ["call","%c%","get_name"], - ["assert","%last_result%","=","test2"] - ]`) - - - // CALL LOOP - - multicall(t, bc, "ac3", `[ - ["let","list",["first","second","third"]], - ["foreach","item","%list%"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","add","%item%"], - ["loop"] - ]`) - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], - ["assert","%last_result%","=","first"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], - ["assert","%last_result%","=","second"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], - ["assert","%last_result%","=","third"] - ]`) - - multicall(t, bc, "ac3", `[ - ["let","list",["1st","2nd","3rd"]], - ["let","n",1], - ["foreach","item","%list%"], - ["tostring","%n%"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set","%last_result%","%item%"], - ["add","%n%",1], - ["store","n"], - ["loop"] - ]`) - - multicall(t, bc, "ac1", `[ - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], - ["assert","%last_result%","=","1st"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], - ["assert","%last_result%","=","2nd"], - ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], - ["assert","%last_result%","=","3rd"] - ]`) - - - - // PCALL - - multicall(t, bc, "ac1", `[ - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], - ["get","%last_result%",1], - ["assert","%last_result%","=",true], - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"], - ["get","%last_result%",1], - ["assert","%last_result%","=",false] - ]`) - - multicall(t, bc, "ac3", `[ - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","1st"], - ["get","%last_result%",1], - ["assert","%last_result%","=",true], - - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], - ["store","ret"], - ["get","%ret%",1], - ["assert","%last_result%","=",true], - ["get","%ret%",2], - ["assert","%last_result%","=","1st"], - - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",22], - ["get","%last_result%",1], - ["assert","%last_result%","=",false], - - ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], - ["store","ret"], - ["get","%ret%",1], - ["assert","%last_result%","=",true], - ["get","%ret%",2], - ["assert","%last_result%","=","1st"], - - ["return","%last_result%"] - ]`, ``, `"1st"`) - - - - // MULTICALL ON ACCOUNT ------------------------------------------ - - - //deploy ac0 0 c1 test.lua - //deploy ac0 0 c2 test.lua - //deploy ac0 0 c3 test.lua - - // c1: AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9 - // c2: Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4 - // c3: AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK - - multicall(t, bc, "ac0", `[ - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","testing multicall"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","contract 2"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","third one"] - ]`) - - multicall(t, bc, "ac0", `[ - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], - ["assert","%last_result%","=","testing multicall"], - ["store","r1"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], - ["assert","%last_result%","=","contract 2"], - ["store","r2"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], - ["assert","%last_result%","=","third one"], - ["store","r3"], - ["return","%r1%","%r2%","%r3%"] - ]`, ``, `["testing multicall","contract 2","third one"]`) - - multicall(t, bc, "ac0", `[ - ["fromjson","{}"], - ["store","res"], - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], - ["set","%res%","r1","%last_result%"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], - ["set","%res%","r2","%last_result%"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], - ["set","%res%","r3","%last_result%"], - ["return","%res%"] - ]`, ``, `{"r1":"testing multicall","r2":"contract 2","r3":"third one"}`) - + ["return","%last_result%"] + ]`, ``, `"0345679IJLNOP"`) - multicall(t, bc, "ac0", `[ - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","wohooooooo"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","it works!"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","it really works!"] - ]`) - multicall(t, bc, "ac0", `[ - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], - ["assert","%last_result%","=","wohooooooo"], - ["store","r1"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], - ["assert","%last_result%","=","it works!"], - ["store","r2"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], - ["assert","%last_result%","=","it really works!"], - ["store","r3"], - ["return","%r1%","%r2%","%r3%"] - ]`, ``, `["wohooooooo","it works!","it really works!"]`) - multicall(t, bc, "ac0", `[ - ["fromjson","{}"], - ["store","res"], - ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], - ["set","%res%","r1","%last_result%"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], - ["set","%res%","r2","%last_result%"], - ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], - ["set","%res%","r3","%last_result%"], - ["return","%res%"] - ]`, ``, `{"r1":"wohooooooo","r2":"it works!","r3":"it really works!"}`) + + // FOR + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["loop"], + ["return","%n%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tobignum","10000000000000000001"], + ["store","to_add"], + ["tobignum","100000000000000000000"], + + ["for","n",1,3], + ["add","%last_result%","%to_add%"], + ["loop"], + + ["tostring","%last_result%"], + ["return","%last_result%"] + ]`, ``, `"130000000000000000003"`) + + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `99`) + + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",5,1,-1], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",5,1], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `0`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",1,5,-1], + ["add","%last_result%",1], + ["loop"], + ["return","%last_result%"] + ]`, ``, `0`) + + + + // FOREACH + + multicall(t, bc, "ac1", `[ + ["let","list",[11,22,33]], + ["let","r",0], + ["foreach","item","%list%"], + ["add","%r%","%item%"], + ["store","r"], + ["loop"], + ["return","%r%"] + ]`, ``, `66`) + + multicall(t, bc, "ac1", `[ + ["let","list",[11,22,33]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `3`) + + multicall(t, bc, "ac1", `[ + ["let","list",[]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `0`) + + multicall(t, bc, "ac1", `[ + ["let","list",["one",1,"two",2,2.5,true,false]], + ["let","counter",0], + ["foreach","item","%list%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `7`) + + multicall(t, bc, "ac1", `[ + ["let","list",[10,21,32]], + ["let","r",0], + ["foreach","item","%list%"], + ["if","%item%","<",30], + ["add","%r%","%item%"], + ["store","r"], + ["end"], + ["loop"], + ["return","%r%"] + ]`, ``, `31`) + + + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","obj",{"one":1,"two":2,"three":3}], + ["get_keys","%obj%"], + ["foreach","key","%last_result%"], + ["concat","%str%","%key%"], + ["store","str"], + ["loop"], + ["return","%str%"] + ]`, ``, `"onethreetwo"`) + + + + // FORPAIR + + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","sum",0], + ["let","obj",{"one":1,"two":2,"three":3}], + ["forpair","key","value","%obj%"], + ["concat","%str%","%key%"], + ["store","str"], + ["add","%sum%","%value%"], + ["store","sum"], + ["loop"], + ["return","%str%","%sum%"] + ]`, ``, `["onethreetwo",6]`) + + multicall(t, bc, "ac1", `[ + ["let","str",""], + ["let","sum",0], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["concat","%str%","%key%"], + ["store","str"], + ["add","%sum%","%value%"], + ["store","sum"], + ["loop"], + ["return","%str%","%sum%"] + ]`, ``, `["fouronethreetwo",12]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","values",[]], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["insert","%names%","%key%"], + ["insert","%values%","%value%"], + ["loop"], + ["return","%names%","%values%"] + ]`, ``, `[["four","one","three","two"],[4.5,1.5,3.5,2.5]]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","values",[]], + ["let","obj",{"one":1.5,"two":2.5,"three":3.5,"four":4.5}], + ["forpair","key","value","%obj%"], + ["insert","%names%","%key%"], + ["insert","%values%","%value%"], + ["loop"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","sort","%values%"], + ["store","values"], + ["return","%names%","%values%"] + ]`, ``, `[["four","one","three","two"],[1.5,2.5,3.5,4.5]]`) + + multicall(t, bc, "ac1", `[ + ["let","obj",{}], + ["let","counter",0], + ["forpair","key","value","%obj%"], + ["add","%counter%",1], + ["store","counter"], + ["loop"], + ["return","%counter%"] + ]`, ``, `0`) + + + + // FOR "BREAK" + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["if","%n%","=",5], + ["let","n",500], + ["end"], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["if","%n%","=",475], + ["let","n",2], + ["end"], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["if","%n%","=",5], + ["break"], + ["end"], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["let","c",0], + ["for","n",1,10], + ["add","%c%",1], + ["store","c"], + ["break","if","%n%","=",5], + ["loop"], + ["return","%c%"] + ]`, ``, `5`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["if","%n%","=",475], + ["break"], + ["end"], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["tonumber","0"], + ["for","n",500,10,-5], + ["add","%last_result%",1], + ["break","if","%n%","=",475], + ["loop"], + ["return","%last_result%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["loop"], + ["return","%n%"] + ]`, ``, `6`) + + multicall(t, bc, "ac1", `[ + ["for","n",1,5], + ["break"], + ["loop"], + ["return","%n%"] + ]`, ``, `1`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","list",["one","two","three","four"]], + ["foreach","item","%list%"], + ["if","%item%","=","three"], + ["break"], + ["end"], + ["insert","%names%","%item%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["one","two"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","list",["one","two","three","four"]], + ["foreach","item","%list%"], + ["break","if","%item%","=","three"], + ["insert","%names%","%item%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["one","two"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","obj",{"one":true,"two":false,"three":false,"four":true}], + ["forpair","key","value","%obj%"], + ["if","%value%","=",false], + ["break"], + ["end"], + ["insert","%names%","%key%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["four","one"]`) + + multicall(t, bc, "ac1", `[ + ["let","names",[]], + ["let","obj",{"one":true,"two":false,"three":false,"four":true}], + ["forpair","key","value","%obj%"], + ["break","if","%value%","=",false], + ["insert","%names%","%key%"], + ["loop"], + ["return","%names%"] + ]`, ``, `["four","one"]`) + + + + // RETURN before the end + + multicall(t, bc, "ac1", `[ + ["let","v",123], + ["if","%v%",">",100], + ["return"], + ["end"], + ["let","v",500], + ["return","%v%"] + ]`, ``, ``) + + multicall(t, bc, "ac1", `[ + ["let","v",123], + ["if","%v%",">",200], + ["return"], + ["end"], + ["let","v",500], + ["return","%v%"] + ]`, ``, `500`) + + + + // FULL LOOPS + + multicall(t, bc, "ac1", `[ + ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], + ["call","%c%","inc","n"], + ["call","%c%","get","n"], + ["if","%last_result%",">=",5], + ["return","%last_result%"], + ["end"], + ["loop"] + ]`, ``, `5`) + + + + + // CALLS + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["assert","%last_result%","=",123], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["return","%last_result%"] + ]`, ``, `123`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"] + ]`, `this call should fail`) + + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","test"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","test"] + ]`) + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","wrong"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","wrong"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",123] + ]`, `must be string`) + + multicall(t, bc, "ac3", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["assert","%last_result%","=","test"], + ["return","%last_result%"] + ]`, ``, `"test"`) + + + multicall(t, bc, "ac3", `[ + ["let","c","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA"], + ["call","%c%","set_name","test2"], + ["call","%c%","get_name"], + ["assert","%last_result%","=","test2"] + ]`) + + + // CALL LOOP + + multicall(t, bc, "ac3", `[ + ["let","list",["first","second","third"]], + ["foreach","item","%list%"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","add","%item%"], + ["loop"] + ]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], + ["assert","%last_result%","=","first"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], + ["assert","%last_result%","=","second"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], + ["assert","%last_result%","=","third"] + ]`) + + multicall(t, bc, "ac3", `[ + ["let","list",["1st","2nd","3rd"]], + ["let","n",1], + ["foreach","item","%list%"], + ["tostring","%n%"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set","%last_result%","%item%"], + ["add","%n%",1], + ["store","n"], + ["loop"] + ]`) + + multicall(t, bc, "ac1", `[ + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","1"], + ["assert","%last_result%","=","1st"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","2"], + ["assert","%last_result%","=","2nd"], + ["call","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get","3"], + ["assert","%last_result%","=","3rd"] + ]`) + + + + // PCALL + + multicall(t, bc, "ac1", `[ + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","works"], + ["get","%last_result%",1], + ["assert","%last_result%","=",true], + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","fails"], + ["get","%last_result%",1], + ["assert","%last_result%","=",false] + ]`) + + multicall(t, bc, "ac3", `[ + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name","1st"], + ["get","%last_result%",1], + ["assert","%last_result%","=",true], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["store","ret"], + ["get","%ret%",1], + ["assert","%last_result%","=",true], + ["get","%ret%",2], + ["assert","%last_result%","=","1st"], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","set_name",22], + ["get","%last_result%",1], + ["assert","%last_result%","=",false], + + ["pcall","AmhbUWkqenFtgKLnbDd1NXHce7hn35pcHWYRWBnq5vauLfEQXXRA","get_name"], + ["store","ret"], + ["get","%ret%",1], + ["assert","%last_result%","=",true], + ["get","%ret%",2], + ["assert","%last_result%","=","1st"], + + ["return","%last_result%"] + ]`, ``, `"1st"`) + + + + // MULTICALL ON ACCOUNT ------------------------------------------ + + + //deploy ac0 0 c1 test.lua + //deploy ac0 0 c2 test.lua + //deploy ac0 0 c3 test.lua + + // c1: AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9 + // c2: Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4 + // c3: AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","testing multicall"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","contract 2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","third one"] + ]`) + + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["assert","%last_result%","=","testing multicall"], + ["store","r1"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["assert","%last_result%","=","contract 2"], + ["store","r2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["assert","%last_result%","=","third one"], + ["store","r3"], + ["return","%r1%","%r2%","%r3%"] + ]`, ``, `["testing multicall","contract 2","third one"]`) + + multicall(t, bc, "ac0", `[ + ["fromjson","{}"], + ["store","res"], + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["set","%res%","r1","%last_result%"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["set","%res%","r2","%last_result%"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["set","%res%","r3","%last_result%"], + ["return","%res%"] + ]`, ``, `{"r1":"testing multicall","r2":"contract 2","r3":"third one"}`) + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","set_name","wohooooooo"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","set_name","it works!"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","set_name","it really works!"] + ]`) - // aergo BALANCE and SEND + multicall(t, bc, "ac0", `[ + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["assert","%last_result%","=","wohooooooo"], + ["store","r1"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["assert","%last_result%","=","it works!"], + ["store","r2"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["assert","%last_result%","=","it really works!"], + ["store","r3"], + ["return","%r1%","%r2%","%r3%"] + ]`, ``, `["wohooooooo","it works!","it really works!"]`) - multicall(t, bc, "ac5", `[ - ["balance"], - ["tostring","%last_result%"], - ["assert","%last_result%","=","10000000000000000000"], - ["return","%last_result%"] - ]`, ``, `"10000000000000000000"`) + multicall(t, bc, "ac0", `[ + ["fromjson","{}"], + ["store","res"], + ["call","AmhXhR3Eguhu5qjVoqcg7aCFMpw1GGZJfqDDqfy6RsTP7MrpWeJ9","get_name"], + ["set","%res%","r1","%last_result%"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","get_name"], + ["set","%res%","r2","%last_result%"], + ["call","AmgtL32d1M56xGENKDnDqXFzkrYJwWidzSMtay3F8fFDU1VAEdvK","get_name"], + ["set","%res%","r3","%last_result%"], + ["return","%res%"] + ]`, ``, `{"r1":"wohooooooo","r2":"it works!","r3":"it really works!"}`) - multicall(t, bc, "ac2", `[ - ["balance"], - ["tostring","%last_result%"], - ["assert","%last_result%","=","10000000000000000000"], - ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], - ["tostring","%last_result%"], - ["assert","%last_result%","=","0"], - ["send","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc","3000000000000000000"], + // aergo BALANCE and SEND - ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], - ["tostring","%last_result%"], - ["assert","%last_result%","=","3000000000000000000"], + multicall(t, bc, "ac5", `[ + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","10000000000000000000"], + ["return","%last_result%"] + ]`, ``, `"10000000000000000000"`) - ["balance"], - ["tostring","%last_result%"], - ["assert","%last_result%","=","7000000000000000000"], + multicall(t, bc, "ac2", `[ + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","10000000000000000000"], - ["return","%last_result%"] - ]`, ``, `"7000000000000000000"`) + ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","0"], + ["send","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc","3000000000000000000"], + ["balance","AmgHyfkUt5iuXJKZNTrdthtXWLLJCrKWdJ6H6Yshn6ZR285Wr2Hc"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","3000000000000000000"], - // SECURITY CHECKS + ["balance"], + ["tostring","%last_result%"], + ["assert","%last_result%","=","7000000000000000000"], - // it should not be possible to call the code from another account + ["return","%last_result%"] + ]`, ``, `"7000000000000000000"`) - // a. from an account (via multicall, using the 'call' command) - multicall(t, bc, "ac1", `[ - ["call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], - ["return","%last_result%"] - ]`, `nd contract`) + // SECURITY CHECKS - // b. from an account (via a call tx) + // it should not be possible to call the code from another account - call(t, bc, "ac1", 0, "ac1", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + // a. from an account (via multicall, using the 'call' command) - call(t, bc, "ac1", 0, "ac2", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + multicall(t, bc, "ac1", `[ + ["call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) - // c. from a contract (calling back) + // b. from an account (via a call tx) - multicall(t, bc, "ac1", `[ - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]], - ["return","%last_result%"] - ]`, `nd contract`) + call(t, bc, "ac1", 0, "ac1", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + call(t, bc, "ac1", 0, "ac2", "execute", `[[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) - // d. from a contract (calling another account) - multicall(t, bc, "ac1", `[ - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], - ["return","%last_result%"] - ]`, `nd contract`) + // c. from a contract (calling back) + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) - // e. from a contract (via a call txn) - call(t, bc, "ac1", 0, "c2", "call", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + // d. from a contract (calling another account) - call(t, bc, "ac1", 0, "c2", "call", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","call","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]], + ["return","%last_result%"] + ]`, `nd contract`) - // system.isContract() should return false on user accounts + // e. from a contract (via a call txn) - call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"]`, ``, `false`) + call(t, bc, "ac1", 0, "c2", "call", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) - call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"]`, ``, `false`) + call(t, bc, "ac1", 0, "c2", "call", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2","execute",[["add",11,22],["return","%last_result%"]]]`, `nd contract`, ``) - multicall(t, bc, "ac1", `[ - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"], - ["assert","%last_result%","=",false], - ["return","%last_result%"] - ]`, ``, `false`) - multicall(t, bc, "ac1", `[ - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"], - ["assert","%last_result%","=",false], - ["return","%last_result%"] - ]`, ``, `false`) + // system.isContract() should return false on user accounts + call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"]`, ``, `false`) - // on a contract called by multicall, the system.getSender() and system.getOrigin() must be the same + call(t, bc, "ac1", 0, "c2", "is_contract", `["AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"]`, ``, `false`) - multicall(t, bc, "ac1", `[ - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","sender"], - ["store","sender"], - ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","origin"], - ["store","origin"], - ["assert","%sender%","=","%origin%"], - ["return","%sender%"] - ]`, ``, `"AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"`) + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"], + ["assert","%last_result%","=",false], + ["return","%last_result%"] + ]`, ``, `false`) + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","is_contract","AmgeSw3M3V3orBMjf1j98kGne4WycnmQWVTJe6MYNrQ2wuVz3Li2"], + ["assert","%last_result%","=",false], + ["return","%last_result%"] + ]`, ``, `false`) + + // on a contract called by multicall, the system.getSender() and system.getOrigin() must be the same + + multicall(t, bc, "ac1", `[ + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","sender"], + ["store","sender"], + ["call","Amh8PekqkDmLiwE6FUX6JejjWk3R54cmTaa1Tc1VHZmTRJMruWe4","origin"], + ["store","origin"], + ["assert","%sender%","=","%origin%"], + ["return","%sender%"] + ]`, ``, `"AmgMPiyZYr19kQ1kHFNiGenez1CRTBqNWqppj6gGZGEP6qszDGe1"`) + + } } // ---------------------------------------------------------------------------- From 10ba4648e89352d4888ba215874c50f87468ee84 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Wed, 13 Dec 2023 19:59:56 +0000 Subject: [PATCH 15/49] fix build after state refactoring --- contract/contract.go | 4 ++-- contract/vm_dummy/vm_dummy.go | 8 ++++---- state/contract.go | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/contract/contract.go b/contract/contract.go index 4e63d0bbc..f34693d70 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -118,9 +118,9 @@ func Execute( // open the contract state var contractState *state.ContractState if isMultiCall { - contractState = bs.GetMultiCallState(sender.AccountID(), sender.State()) + contractState = state.GetMultiCallState(sender.AccountID(), sender.State()) } else { - contractState, err := state.OpenContractState(receiver.AccountID(), receiver.State(), bs.StateDB) + contractState, err = state.OpenContractState(receiver.AccountID(), receiver.State(), bs.StateDB) } if err != nil { return diff --git a/contract/vm_dummy/vm_dummy.go b/contract/vm_dummy/vm_dummy.go index 191b750ec..d1a23092f 100644 --- a/contract/vm_dummy/vm_dummy.go +++ b/contract/vm_dummy/vm_dummy.go @@ -463,11 +463,11 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAcce contractId := types.ToAccountID(l.recipient()) - var contractState *state.V + var contractState *state.AccountState if l.isMultiCall() { contractState = creatorState } else { - contractState, err := state.GetAccountState(l.recipient(), bs.StateDB) + contractState, err = state.GetAccountState(l.recipient(), bs.StateDB) } if err != nil { return err @@ -475,9 +475,9 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAcce var eContractState *state.ContractState if l.isMultiCall() { - eContractState = bs.GetMultiCallState(creatorId, creatorState.State()) + eContractState = state.GetMultiCallState(creatorId, creatorState.State()) } else { - eContractState, err := state.OpenContractState(contractId, contractState.State(), bs.StateDB) + eContractState, err = state.OpenContractState(contractId, contractState.State(), bs.StateDB) } if err != nil { return err diff --git a/state/contract.go b/state/contract.go index c3fb7112a..0b657c112 100644 --- a/state/contract.go +++ b/state/contract.go @@ -11,14 +11,6 @@ import ( "github.com/aergoio/aergo/v2/types" ) -func (states *StateDB) GetMultiCallState(aid types.AccountID, st *types.State) (*ContractState) { - res := &ContractState{ - State: st, - account: aid, - } - return res -} - type ContractState struct { *types.State account types.AccountID @@ -172,6 +164,14 @@ func (cs *ContractState) cache() *statedb.StateBuffer { //---------------------------------------------------------------// // global functions +func GetMultiCallState(aid types.AccountID, st *types.State) (*ContractState) { + res := &ContractState{ + State: st, + account: aid, + } + return res +} + func OpenContractStateAccount(aid types.AccountID, states *statedb.StateDB) (*ContractState, error) { st, err := states.GetAccountState(aid) if err != nil { From 713d0decd13ac3718aa4d45f8bf9ca5bb585e729 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Thu, 14 Dec 2023 20:40:03 +0000 Subject: [PATCH 16/49] compile the multicall code on demand --- contract/vm.go | 18 +- contract/vm_multicall.go | 585 +++++++++++++++++++-------------------- 2 files changed, 293 insertions(+), 310 deletions(-) diff --git a/contract/vm.go b/contract/vm.go index 6adfb5766..5cd3f4377 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -1357,13 +1357,23 @@ func getContract(contractState *state.ContractState, bs *state.BlockState) []byt } func getMultiCallContract(contractState *state.ContractState) []byte { - code := luacUtil.LuaCode(multicall_payload) - if !code.IsValidFormat() { - ctrLgr.Warn().Msg("multicall_payload") + + if multicall_payload == nil { + var err error + multicall_payload, err = Compile(multicall_code, nil) + if err != nil { + ctrLgr.Error().Err(err).Msg("multicall_payload") + return nil + } + } + + if !multicall_payload.IsValidFormat() { + ctrLgr.Error().Msg("multicall_payload: invalid format") return nil } + contractState.SetMultiCallCode(multicall_payload) - return code.ByteCode() + return multicall_payload.ByteCode() } func GetABI(contractState *state.ContractState, bs *state.BlockState) (*types.ABI, error) { diff --git a/contract/vm_multicall.go b/contract/vm_multicall.go index 378565256..6dd79ed2f 100644 --- a/contract/vm_multicall.go +++ b/contract/vm_multicall.go @@ -1,309 +1,282 @@ package contract -var multicall_payload = []byte { - 0x9a,0x12,0x00,0x00,0x1b,0x4c,0x4a,0x02,0x0a,0x25,0x02,0x00,0x03,0x00,0x02, - 0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00, - 0x00,0x00,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74, - 0x37,0x02,0x01,0x04,0x00,0x03,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, - 0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x47,0x03,0x01,0x00, - 0x43,0x01,0x00,0x00,0x0a,0x76,0x61,0x6c,0x75,0x65,0x09,0x63,0x61,0x6c,0x6c,0x0d, - 0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x41,0x02,0x00,0x05,0x00,0x03,0x01,0x08, - 0x34,0x00,0x03,0x00,0x36,0x01,0x00,0x00,0x36,0x03,0x01,0x00,0x39,0x03,0x02,0x03, - 0x47,0x04,0x00,0x00,0x41,0x01,0x01,0x00,0x3f,0x01,0x00,0x00,0x4c,0x00,0x02,0x00, - 0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x0a,0x70, - 0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x53,0x02,0x01,0x07,0x00,0x04, - 0x01,0x0b,0x34,0x01,0x03,0x00,0x36,0x02,0x00,0x00,0x36,0x04,0x01,0x00,0x39,0x04, - 0x02,0x04,0x39,0x04,0x03,0x04,0x12,0x06,0x00,0x00,0x42,0x04,0x02,0x02,0x47,0x05, - 0x01,0x00,0x41,0x02,0x01,0x00,0x3f,0x02,0x00,0x00,0x4c,0x01,0x02,0x00,0x0a,0x76, - 0x61,0x6c,0x75,0x65,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61, - 0x63,0x74,0x0a,0x70,0x63,0x61,0x6c,0x6c,0x03,0x80,0x80,0xc0,0x99,0x04,0x42,0x00, - 0x01,0x06,0x00,0x04,0x00,0x07,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x36,0x03, - 0x02,0x00,0x39,0x03,0x03,0x03,0x12,0x05,0x00,0x00,0x42,0x03,0x02,0x00,0x43,0x01, - 0x00,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e,0x63,0x65,0x0d,0x63,0x6f,0x6e,0x74,0x72, - 0x61,0x63,0x74,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75, - 0x6d,0x29,0x00,0x02,0x06,0x00,0x02,0x00,0x05,0x36,0x02,0x00,0x00,0x39,0x02,0x01, - 0x02,0x12,0x04,0x00,0x00,0x12,0x05,0x01,0x00,0x44,0x02,0x03,0x00,0x09,0x73,0x65, - 0x6e,0x64,0x0d,0x63,0x6f,0x6e,0x74,0x72,0x61,0x63,0x74,0x43,0x00,0x03,0x07,0x00, - 0x02,0x00,0x0a,0x0f,0x00,0x02,0x00,0x58,0x03,0x05,0x80,0x36,0x03,0x00,0x00,0x12, - 0x05,0x01,0x00,0x12,0x06,0x02,0x00,0x42,0x03,0x03,0x02,0x12,0x01,0x03,0x00,0x36, - 0x03,0x01,0x00,0x3c,0x01,0x00,0x03,0x4b,0x00,0x01,0x00,0x09,0x76,0x61,0x72,0x73, - 0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x2c, - 0x00,0x01,0x03,0x00,0x02,0x00,0x05,0x36,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x39, - 0x02,0x01,0x02,0x3c,0x02,0x00,0x01,0x4b,0x00,0x01,0x00,0x10,0x6c,0x61,0x73,0x74, - 0x5f,0x72,0x65,0x73,0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x0f,0x00,0x02,0x03, - 0x00,0x00,0x00,0x02,0x38,0x02,0x01,0x00,0x4c,0x02,0x02,0x00,0x0f,0x00,0x03,0x03, - 0x00,0x00,0x00,0x02,0x3c,0x02,0x01,0x00,0x4b,0x00,0x01,0x00,0x28,0x02,0x00,0x03, - 0x00,0x02,0x00,0x05,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00, - 0x41,0x00,0x00,0x01,0x4b,0x00,0x01,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x0a, - 0x74,0x61,0x62,0x6c,0x65,0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00, - 0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0b,0x72,0x65, - 0x6d,0x6f,0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0f,0x00,0x01,0x02,0x00,0x00, - 0x00,0x02,0x15,0x01,0x00,0x00,0x4c,0x01,0x02,0x00,0x55,0x00,0x01,0x09,0x00,0x03, - 0x01,0x0f,0x34,0x01,0x00,0x00,0x36,0x02,0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02, - 0x02,0x04,0x48,0x05,0x03,0x80,0x15,0x07,0x01,0x00,0x16,0x07,0x00,0x07,0x3c,0x05, - 0x07,0x01,0x46,0x05,0x03,0x03,0x52,0x05,0xfb,0x7f,0x36,0x02,0x01,0x00,0x39,0x02, - 0x02,0x02,0x12,0x04,0x01,0x00,0x42,0x02,0x02,0x01,0x4c,0x01,0x02,0x00,0x09,0x73, - 0x6f,0x72,0x74,0x0a,0x74,0x61,0x62,0x6c,0x65,0x0a,0x70,0x61,0x69,0x72,0x73,0x02, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x20,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x21,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x22,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x23,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x25,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x0f,0x00,0x02,0x03,0x00,0x00,0x00,0x02,0x24,0x02,0x01,0x00,0x4c,0x02,0x02,0x00, - 0x23,0x00,0x01,0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01, - 0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00,0x09,0x73,0x71,0x72,0x74,0x0b,0x62,0x69, - 0x67,0x6e,0x75,0x6d,0x32,0x02,0x00,0x04,0x00,0x02,0x01,0x06,0x36,0x00,0x00,0x00, - 0x39,0x00,0x01,0x00,0x34,0x02,0x03,0x00,0x47,0x03,0x00,0x00,0x3f,0x03,0x00,0x00, - 0x44,0x00,0x02,0x00,0x0b,0x63,0x6f,0x6e,0x63,0x61,0x74,0x0a,0x74,0x61,0x62,0x6c, - 0x65,0x03,0x80,0x80,0xc0,0x99,0x04,0x25,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36, - 0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0b, - 0x66,0x6f,0x72,0x6d,0x61,0x74,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x02,0x00, - 0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00, - 0x00,0x43,0x00,0x00,0x00,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67, - 0x24,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00,0x00,0x39,0x00,0x01,0x00, - 0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x0a,0x6d,0x61,0x74,0x63,0x68,0x0b,0x73, - 0x74,0x72,0x69,0x6e,0x67,0x23,0x02,0x00,0x03,0x00,0x02,0x00,0x04,0x36,0x00,0x00, - 0x00,0x39,0x00,0x01,0x00,0x47,0x02,0x00,0x00,0x43,0x00,0x00,0x00,0x09,0x67,0x73, - 0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x25,0x00,0x01,0x04,0x00,0x02,0x00, - 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, - 0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65,0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x1c, - 0x00,0x01,0x04,0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44, - 0x01,0x02,0x00,0x0d,0x74,0x6f,0x6e,0x75,0x6d,0x62,0x65,0x72,0x1c,0x00,0x01,0x04, - 0x00,0x01,0x00,0x03,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x44,0x01,0x02,0x00, - 0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x23,0x00,0x01,0x04,0x00,0x02,0x00, - 0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00,0x00,0x44,0x01,0x02, - 0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x23,0x00,0x01, - 0x04,0x00,0x02,0x00,0x04,0x36,0x01,0x00,0x00,0x39,0x01,0x01,0x01,0x12,0x03,0x00, - 0x00,0x44,0x01,0x02,0x00,0x0b,0x64,0x65,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f, - 0x6e,0x70,0x02,0x00,0x08,0x00,0x05,0x01,0x0e,0x36,0x00,0x00,0x00,0x36,0x02,0x01, - 0x00,0x47,0x04,0x00,0x00,0x41,0x02,0x00,0x02,0x27,0x03,0x02,0x00,0x36,0x04,0x03, - 0x00,0x39,0x04,0x04,0x04,0x34,0x06,0x03,0x00,0x47,0x07,0x00,0x00,0x3f,0x07,0x00, - 0x00,0x42,0x04,0x02,0x02,0x26,0x03,0x04,0x03,0x42,0x00,0x03,0x01,0x4b,0x00,0x01, - 0x00,0x0b,0x65,0x6e,0x63,0x6f,0x64,0x65,0x09,0x6a,0x73,0x6f,0x6e,0x17,0x61,0x73, - 0x73,0x65,0x72,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x65,0x64,0x3a,0x20, - 0x09,0x65,0x76,0x61,0x6c,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x03,0x80,0x80,0xc0, - 0x99,0x04,0x8e,0x02,0x00,0x01,0x09,0x00,0x08,0x00,0x36,0x36,0x01,0x00,0x00,0x12, - 0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07,0x01,0x01,0x00,0x58,0x01,0x21,0x80,0x15, - 0x01,0x00,0x00,0x29,0x02,0x03,0x00,0x03,0x02,0x01,0x00,0x58,0x01,0x2c,0x80,0x36, - 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x01,0x00,0x29, - 0x05,0x01,0x00,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x24,0x80,0x36, - 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0xff,0xff,0x29, - 0x05,0xff,0xff,0x42,0x01,0x04,0x02,0x07,0x01,0x03,0x00,0x58,0x01,0x1c,0x80,0x36, - 0x01,0x01,0x00,0x39,0x01,0x02,0x01,0x12,0x03,0x00,0x00,0x29,0x04,0x02,0x00,0x29, - 0x05,0xfe,0xff,0x42,0x01,0x04,0x02,0x36,0x02,0x04,0x00,0x38,0x02,0x01,0x02,0x0a, - 0x02,0x00,0x00,0x58,0x02,0x12,0x80,0x36,0x02,0x04,0x00,0x38,0x00,0x01,0x02,0x58, - 0x01,0x0f,0x80,0x36,0x01,0x00,0x00,0x12,0x03,0x00,0x00,0x42,0x01,0x02,0x02,0x07, - 0x01,0x05,0x00,0x58,0x01,0x0a,0x80,0x36,0x01,0x06,0x00,0x12,0x03,0x00,0x00,0x42, - 0x01,0x02,0x04,0x48,0x04,0x04,0x80,0x36,0x06,0x07,0x00,0x12,0x08,0x05,0x00,0x42, - 0x06,0x02,0x02,0x3c,0x06,0x04,0x00,0x46,0x04,0x03,0x03,0x52,0x04,0xfa,0x7f,0x4c, - 0x00,0x02,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x0a, - 0x70,0x61,0x69,0x72,0x73,0x0a,0x74,0x61,0x62,0x6c,0x65,0x09,0x76,0x61,0x72,0x73, - 0x06,0x25,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79, - 0x70,0x65,0xc8,0x09,0x00,0x01,0x18,0x00,0x1a,0x01,0x83,0x02,0x2b,0x01,0x02,0x00, - 0x2b,0x02,0x01,0x00,0x2c,0x03,0x0b,0x00,0x2b,0x0c,0x01,0x00,0x29,0x0d,0x01,0x00, - 0x15,0x0e,0x00,0x00,0x03,0x0d,0x0e,0x00,0x58,0x0e,0xfa,0x80,0x55,0x0e,0xf9,0x80, - 0x38,0x0e,0x0d,0x00,0x34,0x0f,0x00,0x00,0x36,0x10,0x00,0x00,0x12,0x12,0x0e,0x00, - 0x42,0x10,0x02,0x04,0x58,0x13,0x08,0x80,0x09,0x13,0x00,0x00,0x58,0x15,0x02,0x80, - 0x3c,0x14,0x13,0x0f,0x58,0x15,0x04,0x80,0x36,0x15,0x01,0x00,0x12,0x17,0x14,0x00, - 0x42,0x15,0x02,0x02,0x3c,0x15,0x13,0x0f,0x45,0x13,0x03,0x03,0x52,0x13,0xf6,0x7f, - 0x36,0x10,0x02,0x00,0x39,0x10,0x03,0x10,0x12,0x12,0x0f,0x00,0x29,0x13,0x01,0x00, - 0x42,0x10,0x03,0x02,0x36,0x11,0x04,0x00,0x38,0x11,0x10,0x11,0x0f,0x00,0x11,0x00, - 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x12,0x12,0x11,0x00, - 0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00,0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02, - 0x36,0x13,0x06,0x00,0x38,0x13,0x10,0x13,0x0e,0x00,0x13,0x00,0x58,0x13,0xb5,0x80, - 0x36,0x13,0x07,0x00,0x3d,0x12,0x08,0x13,0x58,0x12,0xb2,0x80,0x07,0x10,0x09,0x00, - 0x58,0x12,0x08,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, - 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, - 0x58,0x12,0xa8,0x80,0x07,0x10,0x0b,0x00,0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00, - 0x58,0x12,0x02,0x80,0x2b,0x01,0x01,0x00,0x58,0x12,0xa2,0x80,0x0e,0x00,0x02,0x00, - 0x58,0x12,0xa0,0x80,0x36,0x12,0x0a,0x00,0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00, - 0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02,0x12,0x01,0x12,0x00,0x12,0x02,0x01,0x00, - 0x58,0x12,0x98,0x80,0x07,0x10,0x0c,0x00,0x58,0x12,0x08,0x80,0x0e,0x00,0x01,0x00, - 0x58,0x12,0x02,0x80,0x13,0x01,0x02,0x00,0x58,0x12,0x92,0x80,0x2b,0x01,0x01,0x00, - 0x58,0x12,0x01,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x8e,0x80,0x07,0x10,0x0d,0x00, - 0x58,0x12,0x02,0x80,0x2b,0x01,0x02,0x00,0x58,0x12,0x8a,0x80,0x07,0x10,0x0e,0x00, - 0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x04,0x80,0x27,0x05,0x0f,0x00, - 0x34,0x07,0x00,0x00,0x3a,0x08,0x02,0x0f,0x58,0x12,0x82,0x80,0x07,0x10,0x10,0x00, - 0x58,0x12,0x0e,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x0c,0x80,0x3a,0x05,0x02,0x0f, - 0x3a,0x07,0x03,0x0f,0x36,0x12,0x04,0x00,0x39,0x12,0x11,0x12,0x12,0x14,0x07,0x00, - 0x42,0x12,0x02,0x02,0x12,0x08,0x12,0x00,0x36,0x12,0x07,0x00,0x3a,0x13,0x01,0x08, - 0x38,0x13,0x13,0x07,0x3c,0x13,0x05,0x12,0x58,0x12,0x72,0x80,0x07,0x10,0x12,0x00, - 0x58,0x12,0x1f,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x1d,0x80,0x12,0x03,0x0d,0x00, - 0x27,0x06,0x13,0x00,0x3a,0x04,0x01,0x0f,0x3a,0x0a,0x03,0x0f,0x3a,0x12,0x04,0x0f, - 0x0c,0x0b,0x12,0x00,0x58,0x13,0x01,0x80,0x29,0x0b,0x01,0x00,0x36,0x12,0x07,0x00, - 0x3a,0x13,0x02,0x0f,0x3c,0x13,0x04,0x12,0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00, - 0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00, - 0x58,0x12,0x09,0x80,0x29,0x12,0x00,0x00,0x01,0x0b,0x12,0x00,0x58,0x12,0x04,0x80, - 0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x12,0x0a,0x00,0x58,0x12,0x02,0x80, - 0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x51,0x80, - 0x07,0x10,0x14,0x00,0x58,0x12,0x12,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x10,0x80, - 0x36,0x12,0x02,0x00,0x39,0x12,0x03,0x12,0x12,0x14,0x0f,0x00,0x29,0x15,0x01,0x00, - 0x42,0x12,0x03,0x02,0x07,0x12,0x09,0x00,0x58,0x12,0x07,0x80,0x36,0x12,0x0a,0x00, - 0x36,0x14,0x05,0x00,0x12,0x16,0x0f,0x00,0x42,0x14,0x02,0x00,0x41,0x12,0x00,0x02, - 0x12,0x0c,0x12,0x00,0x58,0x12,0x3f,0x80,0x2b,0x0c,0x02,0x00,0x58,0x12,0x3d,0x80, - 0x07,0x10,0x15,0x00,0x58,0x12,0x2b,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x29,0x80, - 0x07,0x06,0x16,0x00,0x58,0x12,0x0d,0x80,0x16,0x09,0x00,0x09,0x15,0x12,0x08,0x00, - 0x03,0x09,0x12,0x00,0x58,0x12,0x33,0x80,0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08, - 0x3c,0x13,0x04,0x12,0x36,0x12,0x07,0x00,0x38,0x13,0x09,0x08,0x38,0x13,0x13,0x07, - 0x3c,0x13,0x05,0x12,0x12,0x0d,0x03,0x00,0x58,0x12,0x2a,0x80,0x07,0x06,0x13,0x00, - 0x58,0x12,0x16,0x80,0x36,0x12,0x07,0x00,0x36,0x13,0x07,0x00,0x38,0x13,0x04,0x13, - 0x20,0x13,0x0b,0x13,0x3c,0x13,0x04,0x12,0x29,0x12,0x00,0x00,0x01,0x12,0x0b,0x00, - 0x58,0x12,0x04,0x80,0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x00,0x0a,0x12,0x00, - 0x58,0x12,0x1c,0x80,0x29,0x12,0x00,0x00,0x01,0x0b,0x12,0x00,0x58,0x12,0x05,0x80, - 0x36,0x12,0x07,0x00,0x38,0x12,0x04,0x12,0x01,0x12,0x0a,0x00,0x58,0x12,0x01,0x80, - 0x58,0x12,0x14,0x80,0x12,0x0d,0x03,0x00,0x58,0x12,0x12,0x80,0x29,0x0d,0x00,0x00, - 0x58,0x12,0x10,0x80,0x07,0x10,0x17,0x00,0x58,0x12,0x06,0x80,0x0f,0x00,0x01,0x00, - 0x58,0x12,0x04,0x80,0x36,0x12,0x05,0x00,0x12,0x14,0x0f,0x00,0x44,0x12,0x02,0x00, - 0x58,0x12,0x08,0x80,0x0f,0x00,0x01,0x00,0x58,0x12,0x06,0x80,0x36,0x12,0x18,0x00, - 0x2b,0x14,0x01,0x00,0x27,0x15,0x19,0x00,0x12,0x16,0x10,0x00,0x26,0x15,0x16,0x15, - 0x42,0x12,0x03,0x01,0x0f,0x00,0x01,0x00,0x58,0x12,0x11,0x80,0x06,0x10,0x0e,0x00, - 0x58,0x12,0x02,0x80,0x07,0x10,0x10,0x00,0x58,0x12,0x0d,0x80,0x12,0x03,0x0d,0x00, - 0x27,0x06,0x16,0x00,0x3a,0x04,0x01,0x0f,0x29,0x09,0x01,0x00,0x36,0x12,0x07,0x00, - 0x3a,0x13,0x01,0x08,0x3c,0x13,0x04,0x12,0x3a,0x12,0x01,0x08,0x0a,0x12,0x00,0x00, - 0x58,0x12,0x02,0x80,0x2b,0x0c,0x01,0x00,0x58,0x12,0x01,0x80,0x2b,0x0c,0x02,0x00, - 0x0f,0x00,0x0c,0x00,0x58,0x12,0x09,0x80,0x55,0x12,0x07,0x80,0x16,0x0d,0x00,0x0d, - 0x38,0x0e,0x0d,0x00,0x0a,0x0e,0x00,0x00,0x58,0x12,0x03,0x80,0x3a,0x12,0x01,0x0e, - 0x07,0x12,0x15,0x00,0x58,0x12,0xf8,0x7f,0x2b,0x0c,0x01,0x00,0x16,0x0d,0x00,0x0d, - 0x58,0x0e,0x03,0x7f,0x4b,0x00,0x01,0x00,0x18,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64, - 0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x0b,0x61,0x73,0x73, - 0x65,0x72,0x74,0x0b,0x72,0x65,0x74,0x75,0x72,0x6e,0x09,0x65,0x61,0x63,0x68,0x09, - 0x6c,0x6f,0x6f,0x70,0x0a,0x62,0x72,0x65,0x61,0x6b,0x0b,0x6e,0x75,0x6d,0x62,0x65, - 0x72,0x08,0x66,0x6f,0x72,0x0d,0x67,0x65,0x74,0x5f,0x6b,0x65,0x79,0x73,0x0c,0x66, - 0x6f,0x72,0x70,0x61,0x69,0x72,0x07,0x5f,0x5f,0x0c,0x66,0x6f,0x72,0x65,0x61,0x63, - 0x68,0x08,0x65,0x6e,0x64,0x09,0x65,0x6c,0x73,0x65,0x09,0x65,0x6c,0x69,0x66,0x09, - 0x65,0x76,0x61,0x6c,0x07,0x69,0x66,0x10,0x6c,0x61,0x73,0x74,0x5f,0x72,0x65,0x73, - 0x75,0x6c,0x74,0x09,0x76,0x61,0x72,0x73,0x09,0x73,0x6b,0x69,0x70,0x0b,0x75,0x6e, - 0x70,0x61,0x63,0x6b,0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x72,0x65,0x6d,0x6f, - 0x76,0x65,0x0a,0x74,0x61,0x62,0x6c,0x65,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73, - 0x5f,0x61,0x72,0x67,0x0b,0x69,0x70,0x61,0x69,0x72,0x73,0x02,0xc7,0x04,0x02,0x00, - 0x0d,0x00,0x0f,0x01,0x7b,0x34,0x00,0x03,0x00,0x47,0x01,0x00,0x00,0x3f,0x01,0x00, - 0x00,0x3a,0x01,0x01,0x00,0x3a,0x02,0x02,0x00,0x3a,0x03,0x03,0x00,0x2b,0x04,0x01, - 0x00,0x2b,0x05,0x01,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01,0x06,0x12,0x08,0x02, - 0x00,0x29,0x09,0x01,0x00,0x29,0x0a,0x01,0x00,0x42,0x06,0x04,0x02,0x07,0x06,0x02, - 0x00,0x58,0x06,0x07,0x80,0x2b,0x04,0x02,0x00,0x36,0x06,0x00,0x00,0x39,0x06,0x01, - 0x06,0x12,0x08,0x02,0x00,0x29,0x09,0x02,0x00,0x42,0x06,0x03,0x02,0x12,0x02,0x06, - 0x00,0x0b,0x01,0x00,0x00,0x58,0x06,0x03,0x80,0x06,0x02,0x03,0x00,0x58,0x06,0x01, - 0x80,0x58,0x06,0x3b,0x80,0x07,0x02,0x03,0x00,0x58,0x06,0x06,0x80,0x04,0x01,0x03, - 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, - 0x00,0x58,0x06,0x33,0x80,0x07,0x02,0x04,0x00,0x58,0x06,0x06,0x80,0x00,0x03,0x01, - 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, - 0x00,0x58,0x06,0x2b,0x80,0x07,0x02,0x05,0x00,0x58,0x06,0x06,0x80,0x02,0x03,0x01, - 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, - 0x00,0x58,0x06,0x23,0x80,0x07,0x02,0x06,0x00,0x58,0x06,0x06,0x80,0x00,0x01,0x03, - 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, - 0x00,0x58,0x06,0x1b,0x80,0x07,0x02,0x07,0x00,0x58,0x06,0x06,0x80,0x02,0x01,0x03, - 0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01,0x80,0x2b,0x05,0x02, - 0x00,0x58,0x06,0x13,0x80,0x07,0x02,0x08,0x00,0x58,0x06,0x0b,0x80,0x36,0x06,0x00, - 0x00,0x39,0x06,0x08,0x06,0x12,0x08,0x01,0x00,0x12,0x09,0x03,0x00,0x42,0x06,0x03, - 0x02,0x0b,0x06,0x00,0x00,0x58,0x06,0x02,0x80,0x2b,0x05,0x01,0x00,0x58,0x06,0x01, - 0x80,0x2b,0x05,0x02,0x00,0x58,0x06,0x06,0x80,0x36,0x06,0x09,0x00,0x2b,0x08,0x01, - 0x00,0x27,0x09,0x0a,0x00,0x12,0x0a,0x02,0x00,0x26,0x09,0x0a,0x09,0x42,0x06,0x03, - 0x01,0x0f,0x00,0x04,0x00,0x58,0x06,0x01,0x80,0x13,0x05,0x05,0x00,0x15,0x06,0x00, - 0x00,0x29,0x07,0x03,0x00,0x01,0x07,0x06,0x00,0x58,0x06,0x1c,0x80,0x3a,0x02,0x04, - 0x00,0x36,0x06,0x0b,0x00,0x36,0x08,0x0c,0x00,0x12,0x0a,0x00,0x00,0x29,0x0b,0x05, - 0x00,0x15,0x0c,0x00,0x00,0x42,0x08,0x04,0x00,0x41,0x06,0x00,0x02,0x07,0x02,0x0d, - 0x00,0x58,0x07,0x05,0x80,0x0d,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06, - 0x00,0x4c,0x07,0x02,0x00,0x58,0x07,0x0d,0x80,0x07,0x02,0x0e,0x00,0x58,0x07,0x05, - 0x80,0x0c,0x07,0x05,0x00,0x58,0x07,0x01,0x80,0x12,0x07,0x06,0x00,0x4c,0x07,0x02, - 0x00,0x58,0x07,0x06,0x80,0x36,0x07,0x09,0x00,0x2b,0x09,0x01,0x00,0x27,0x0a,0x0a, - 0x00,0x12,0x0b,0x02,0x00,0x26,0x0a,0x0b,0x0a,0x42,0x07,0x03,0x01,0x4c,0x05,0x02, - 0x00,0x07,0x6f,0x72,0x08,0x61,0x6e,0x64,0x0b,0x75,0x6e,0x70,0x61,0x63,0x6b,0x09, - 0x65,0x76,0x61,0x6c,0x19,0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,0x20,0x6e,0x6f, - 0x74,0x20,0x6b,0x6e,0x6f,0x77,0x6e,0x3a,0x20,0x0b,0x61,0x73,0x73,0x65,0x72,0x74, - 0x0a,0x6d,0x61,0x74,0x63,0x68,0x07,0x3c,0x3d,0x06,0x3c,0x07,0x3e,0x3d,0x06,0x3e, - 0x06,0x3d,0x06,0x21,0x08,0x73,0x75,0x62,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x03, - 0x80,0x80,0xc0,0x99,0x04,0xab,0x05,0x00,0x02,0x0e,0x00,0x18,0x02,0x73,0x36,0x02, - 0x00,0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x06,0x02,0x01,0x00,0x58,0x02, - 0x04,0x80,0x36,0x02,0x02,0x00,0x12,0x04,0x00,0x00,0x42,0x02,0x02,0x02,0x12,0x00, - 0x02,0x00,0x36,0x02,0x03,0x00,0x36,0x04,0x01,0x00,0x39,0x04,0x04,0x04,0x12,0x06, - 0x00,0x00,0x27,0x07,0x05,0x00,0x42,0x04,0x03,0x02,0x0a,0x04,0x00,0x00,0x58,0x04, - 0x02,0x80,0x2b,0x04,0x01,0x00,0x58,0x05,0x01,0x80,0x2b,0x04,0x02,0x00,0x27,0x05, - 0x06,0x00,0x42,0x02,0x03,0x01,0x36,0x02,0x01,0x00,0x39,0x02,0x07,0x02,0x12,0x04, - 0x00,0x00,0x27,0x05,0x08,0x00,0x27,0x06,0x09,0x00,0x42,0x02,0x04,0x03,0x36,0x04, - 0x03,0x00,0x29,0x06,0x01,0x00,0x02,0x03,0x06,0x00,0x58,0x06,0x02,0x80,0x2b,0x06, - 0x01,0x00,0x58,0x07,0x01,0x80,0x2b,0x06,0x02,0x00,0x27,0x07,0x0a,0x00,0x42,0x04, - 0x03,0x01,0x09,0x03,0x00,0x00,0x58,0x04,0x48,0x80,0x2b,0x04,0x00,0x00,0x12,0x07, - 0x01,0x00,0x39,0x05,0x0b,0x01,0x42,0x05,0x02,0x02,0x07,0x05,0x0c,0x00,0x58,0x05, - 0x02,0x80,0x29,0x04,0x12,0x00,0x58,0x05,0x06,0x80,0x36,0x05,0x0d,0x00,0x39,0x05, - 0x0e,0x05,0x12,0x07,0x01,0x00,0x27,0x08,0x0f,0x00,0x42,0x05,0x03,0x02,0x12,0x04, - 0x05,0x00,0x36,0x05,0x03,0x00,0x29,0x07,0x00,0x00,0x03,0x07,0x04,0x00,0x58,0x07, - 0x03,0x80,0x29,0x07,0x12,0x00,0x02,0x04,0x07,0x00,0x58,0x07,0x02,0x80,0x2b,0x07, - 0x01,0x00,0x58,0x08,0x01,0x80,0x2b,0x07,0x02,0x00,0x27,0x08,0x10,0x00,0x42,0x05, - 0x03,0x01,0x36,0x05,0x01,0x00,0x39,0x05,0x04,0x05,0x27,0x07,0x11,0x00,0x12,0x08, - 0x00,0x00,0x27,0x09,0x11,0x00,0x26,0x07,0x09,0x07,0x27,0x08,0x12,0x00,0x42,0x05, - 0x03,0x03,0x15,0x07,0x06,0x00,0x21,0x07,0x07,0x04,0x29,0x08,0x00,0x00,0x01,0x08, - 0x07,0x00,0x58,0x08,0x08,0x80,0x12,0x08,0x06,0x00,0x36,0x09,0x01,0x00,0x39,0x09, - 0x13,0x09,0x27,0x0b,0x11,0x00,0x12,0x0c,0x07,0x00,0x42,0x09,0x03,0x02,0x26,0x06, - 0x09,0x08,0x58,0x08,0x0a,0x80,0x29,0x08,0x00,0x00,0x01,0x07,0x08,0x00,0x58,0x08, - 0x07,0x80,0x36,0x08,0x01,0x00,0x39,0x08,0x14,0x08,0x12,0x0a,0x06,0x00,0x29,0x0b, - 0x01,0x00,0x12,0x0c,0x04,0x00,0x42,0x08,0x04,0x02,0x12,0x06,0x08,0x00,0x12,0x08, - 0x05,0x00,0x12,0x09,0x06,0x00,0x26,0x00,0x09,0x08,0x36,0x08,0x01,0x00,0x39,0x08, - 0x07,0x08,0x12,0x0a,0x00,0x00,0x27,0x0b,0x15,0x00,0x27,0x0c,0x09,0x00,0x29,0x0d, - 0x01,0x00,0x42,0x08,0x05,0x02,0x12,0x00,0x08,0x00,0x15,0x08,0x00,0x00,0x09,0x08, - 0x01,0x00,0x58,0x08,0x01,0x80,0x27,0x00,0x11,0x00,0x36,0x04,0x16,0x00,0x39,0x04, - 0x17,0x04,0x12,0x06,0x00,0x00,0x44,0x04,0x02,0x00,0x0b,0x6e,0x75,0x6d,0x62,0x65, - 0x72,0x0b,0x62,0x69,0x67,0x6e,0x75,0x6d,0x07,0x30,0x2a,0x08,0x73,0x75,0x62,0x08, - 0x72,0x65,0x70,0x11,0x28,0x25,0x64,0x2b,0x29,0x25,0x2e,0x28,0x25,0x64,0x2b,0x29, - 0x06,0x30,0x20,0x74,0x6f,0x6b,0x65,0x6e,0x20,0x77,0x69,0x74,0x68,0x20,0x69,0x6e, - 0x76,0x61,0x6c,0x69,0x64,0x20,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x0d,0x64, - 0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x09,0x63,0x61,0x6c,0x6c,0x0d,0x63,0x6f,0x6e, - 0x74,0x72,0x61,0x63,0x74,0x0a,0x61,0x65,0x72,0x67,0x6f,0x0a,0x6c,0x6f,0x77,0x65, - 0x72,0x1a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x69,0x73,0x20, - 0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x05,0x07,0x25,0x2e,0x09,0x67,0x73,0x75,0x62, - 0x2a,0x74,0x68,0x65,0x20,0x61,0x6d,0x6f,0x75,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x74, - 0x61,0x69,0x6e,0x73,0x20,0x69,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x63,0x68,0x61, - 0x72,0x61,0x63,0x74,0x65,0x72,0x0c,0x5b,0x5e,0x30,0x2d,0x39,0x2e,0x5d,0x0a,0x6d, - 0x61,0x74,0x63,0x68,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x0d,0x74,0x6f,0x73,0x74, - 0x72,0x69,0x6e,0x67,0x0b,0x73,0x74,0x72,0x69,0x6e,0x67,0x09,0x74,0x79,0x70,0x65, - 0x02,0x00,0xba,0x05,0x03,0x00,0x03,0x00,0x4f,0x00,0x53,0x34,0x00,0x00,0x00,0x37, - 0x00,0x00,0x00,0x35,0x00,0x01,0x00,0x37,0x00,0x02,0x00,0x35,0x00,0x04,0x00,0x33, - 0x01,0x03,0x00,0x3d,0x01,0x05,0x00,0x33,0x01,0x06,0x00,0x3d,0x01,0x07,0x00,0x33, - 0x01,0x08,0x00,0x3d,0x01,0x09,0x00,0x33,0x01,0x0a,0x00,0x3d,0x01,0x0b,0x00,0x33, - 0x01,0x0c,0x00,0x3d,0x01,0x0d,0x00,0x33,0x01,0x0e,0x00,0x3d,0x01,0x0f,0x00,0x33, - 0x01,0x10,0x00,0x3d,0x01,0x11,0x00,0x33,0x01,0x12,0x00,0x3d,0x01,0x13,0x00,0x33, - 0x01,0x14,0x00,0x3d,0x01,0x15,0x00,0x33,0x01,0x16,0x00,0x3d,0x01,0x17,0x00,0x33, - 0x01,0x18,0x00,0x3d,0x01,0x19,0x00,0x33,0x01,0x1a,0x00,0x3d,0x01,0x1b,0x00,0x33, - 0x01,0x1c,0x00,0x3d,0x01,0x1d,0x00,0x33,0x01,0x1e,0x00,0x3d,0x01,0x1f,0x00,0x33, - 0x01,0x20,0x00,0x3d,0x01,0x21,0x00,0x33,0x01,0x22,0x00,0x3d,0x01,0x23,0x00,0x33, - 0x01,0x24,0x00,0x3d,0x01,0x25,0x00,0x33,0x01,0x26,0x00,0x3d,0x01,0x27,0x00,0x33, - 0x01,0x28,0x00,0x3d,0x01,0x29,0x00,0x33,0x01,0x2a,0x00,0x3d,0x01,0x2b,0x00,0x33, - 0x01,0x2c,0x00,0x3d,0x01,0x2d,0x00,0x33,0x01,0x2e,0x00,0x3d,0x01,0x2f,0x00,0x33, - 0x01,0x30,0x00,0x3d,0x01,0x31,0x00,0x33,0x01,0x32,0x00,0x3d,0x01,0x33,0x00,0x33, - 0x01,0x34,0x00,0x3d,0x01,0x35,0x00,0x33,0x01,0x36,0x00,0x3d,0x01,0x37,0x00,0x33, - 0x01,0x38,0x00,0x3d,0x01,0x39,0x00,0x33,0x01,0x3a,0x00,0x3d,0x01,0x3b,0x00,0x33, - 0x01,0x3c,0x00,0x3d,0x01,0x3d,0x00,0x33,0x01,0x3e,0x00,0x3d,0x01,0x3f,0x00,0x33, - 0x01,0x40,0x00,0x3d,0x01,0x41,0x00,0x33,0x01,0x42,0x00,0x3d,0x01,0x43,0x00,0x37, - 0x00,0x44,0x00,0x33,0x00,0x45,0x00,0x37,0x00,0x46,0x00,0x33,0x00,0x47,0x00,0x37, - 0x00,0x48,0x00,0x33,0x00,0x49,0x00,0x37,0x00,0x4a,0x00,0x33,0x00,0x4b,0x00,0x37, - 0x00,0x4c,0x00,0x36,0x00,0x4d,0x00,0x39,0x00,0x4e,0x00,0x36,0x02,0x48,0x00,0x42, - 0x00,0x02,0x01,0x4b,0x00,0x01,0x00,0x0d,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, - 0x08,0x61,0x62,0x69,0x13,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x62,0x69,0x67, - 0x6e,0x75,0x6d,0x00,0x09,0x65,0x76,0x61,0x6c,0x00,0x0c,0x65,0x78,0x65,0x63,0x75, - 0x74,0x65,0x00,0x10,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x5f,0x61,0x72,0x67,0x00, - 0x0b,0x61,0x63,0x74,0x69,0x6f,0x6e,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x00,0x0d, - 0x66,0x72,0x6f,0x6d,0x6a,0x73,0x6f,0x6e,0x00,0x0b,0x74,0x6f,0x6a,0x73,0x6f,0x6e, - 0x00,0x0d,0x74,0x6f,0x73,0x74,0x72,0x69,0x6e,0x67,0x00,0x0d,0x74,0x6f,0x6e,0x75, - 0x6d,0x62,0x65,0x72,0x00,0x0d,0x74,0x6f,0x62,0x69,0x67,0x6e,0x75,0x6d,0x00,0x0c, - 0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x00,0x09,0x66,0x69,0x6e,0x64,0x00,0x0b,0x73, - 0x75,0x62,0x73,0x74,0x72,0x00,0x0b,0x66,0x6f,0x72,0x6d,0x61,0x74,0x00,0x0b,0x63, - 0x6f,0x6e,0x63,0x61,0x74,0x00,0x09,0x73,0x71,0x72,0x74,0x00,0x08,0x6d,0x6f,0x64, - 0x00,0x08,0x70,0x6f,0x77,0x00,0x08,0x64,0x69,0x76,0x00,0x08,0x6d,0x75,0x6c,0x00, - 0x08,0x73,0x75,0x62,0x00,0x08,0x61,0x64,0x64,0x00,0x0d,0x67,0x65,0x74,0x5f,0x6b, - 0x65,0x79,0x73,0x00,0x0d,0x67,0x65,0x74,0x5f,0x73,0x69,0x7a,0x65,0x00,0x0b,0x72, - 0x65,0x6d,0x6f,0x76,0x65,0x00,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x00,0x08,0x73, - 0x65,0x74,0x00,0x08,0x67,0x65,0x74,0x00,0x0a,0x73,0x74,0x6f,0x72,0x65,0x00,0x08, - 0x6c,0x65,0x74,0x00,0x09,0x73,0x65,0x6e,0x64,0x00,0x0c,0x62,0x61,0x6c,0x61,0x6e, - 0x63,0x65,0x00,0x0f,0x70,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64,0x00,0x0a, - 0x70,0x63,0x61,0x6c,0x6c,0x00,0x0e,0x63,0x61,0x6c,0x6c,0x2d,0x73,0x65,0x6e,0x64, - 0x00,0x09,0x63,0x61,0x6c,0x6c,0x01,0x00,0x00,0x00,0x09,0x73,0x6b,0x69,0x70,0x01, - 0x00,0x06,0x0b,0x69,0x6e,0x73,0x65,0x72,0x74,0x02,0x08,0x6c,0x65,0x74,0x02,0x0a, - 0x73,0x74,0x6f,0x72,0x65,0x02,0x09,0x73,0x65,0x6e,0x64,0x02,0x08,0x73,0x65,0x74, - 0x02,0x0b,0x61,0x73,0x73,0x65,0x72,0x74,0x02,0x09,0x76,0x61,0x72,0x73,0x00,0x7b, - 0x22,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22,0x3a,0x22,0x30,0x2e,0x32,0x22,0x2c, - 0x22,0x6c,0x61,0x6e,0x67,0x75,0x61,0x67,0x65,0x22,0x3a,0x22,0x6c,0x75,0x61,0x22, - 0x2c,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x73,0x22,0x3a,0x5b,0x7b,0x22, - 0x6e,0x61,0x6d,0x65,0x22,0x3a,0x22,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x22,0x2c, - 0x22,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x22,0x3a,0x5b,0x7b,0x22,0x6e, - 0x61,0x6d,0x65,0x22,0x3a,0x22,0x63,0x61,0x6c,0x6c,0x73,0x22,0x7d,0x5d,0x7d,0x5d, - 0x7d, +import ( + luacUtil "github.com/aergoio/aergo/v2/cmd/aergoluac/util" +) + +var multicall_payload luacUtil.LuaCode + +const multicall_code = ` +vars = {} + +skip = {store=true,let=true,set=true,insert=true,assert=true,send=true} + +action = { + + -- contract call + call = function (...) return contract.call(...) end, + ["call-send"] = function (amount,...) return contract.call.value(amount)(...) end, + ["pcall"] = function (...) return {pcall(contract.call,...)} end, + ["pcall-send"] = function (amount,...) return {pcall(contract.call.value(amount),...)} end, + + -- aergo balance and transfer + balance = function (address) return bignum.number(contract.balance(address)) end, + send = function (address,amount) return contract.send(address, amount) end, + + -- variables + let = function (x,y,z) if z then y = convert_bignum(y,z) end vars[x] = y end, + store = function (n) vars[n] = vars['last_result'] end, + + -- tables + get = function (o,k) return o[k] end, + set = function (o,k,v) o[k] = v end, + insert = function (...) table.insert(...) end, -- inserts at the end if no pos informed + remove = function (...) return table.remove(...) end, -- returns the removed item + get_size = function (x) return #x end, + get_keys = function (obj) + local list = {} + for key,_ in pairs(obj) do + list[#list + 1] = key + end + table.sort(list) -- for a deterministic output + return list + end, + + -- math + add = function (x,y) return x+y end, + sub = function (x,y) return x-y end, + mul = function (x,y) return x*y end, + div = function (x,y) return x/y end, + pow = function (x,y) return x^y end, + mod = function (x,y) return x%y end, + sqrt = function (x) return bignum.sqrt(x) end, -- use pow(0.5) for numbers + + -- strings + concat = function (...) return table.concat({...}) end, + format = function (...) return string.format(...) end, -- for concat: ['format','%s%s','%val1%','%val2%'] + substr = function (...) return string.sub(...) end, + find = function (...) return string.match(...) end, + replace = function (...) return string.gsub(...) end, + + -- conversions + tobignum = function (x) return bignum.number(x) end, + tonumber = function (x) return tonumber(x) end, + tostring = function (x) return tostring(x) end, -- bignum to string + tojson = function (x) return json.encode(x) end, + fromjson = function (x) return json.decode(x) end, -- create tables + + -- assertion + assert = function (...) assert(eval(...),"assertion failed: " .. json.encode({...})) end, + } + +function process_arg(arg) + if type(arg) == 'string' then + if #arg >= 3 and string.sub(arg, 1, 1) == '%' and string.sub(arg, -1, -1) == '%' then + local varname = string.sub(arg, 2, -2) + if vars[varname] ~= nil then + arg = vars[varname] + end + end + elseif type(arg) == 'table' then + for k,v in pairs(arg) do arg[k] = process_arg(v) end + end + return arg +end + +function execute(calls) + + local if_on = true + local if_done = false + + local for_cmdpos + local for_var, for_var2, for_type + local for_obj, for_list, for_pos + local for_last, for_increment + local skip_for = false + + local cmdpos = 1 + while cmdpos <= #calls do + local call = calls[cmdpos] + local args = {} -- use a copy of the list because of loops + + -- copy values and process variables + for i,arg in ipairs(call) do + if i == 1 then + args[i] = arg + else + args[i] = process_arg(arg) + end + end + + -- process the command + local cmd = table.remove(args, 1) + local fn = action[cmd] + if fn and if_on then + local result = fn(unpack(args)) + if not skip[cmd] then + vars['last_result'] = result + end + + -- if elif else end + elseif cmd == "if" then + if_on = eval(unpack(args)) + if_done = if_on + elseif cmd == "elif" then + if if_on then + if_on = false + elseif not if_done then + if_on = eval(unpack(args)) + if_done = if_on + end + elseif cmd == "else" then + if_on = (not if_on) and (not if_done) + elseif cmd == "end" then + if_on = true + + -- for foreach forpair break loop + elseif cmd == "foreach" and if_on then + for_var2 = "__" + for_obj = {} + for_list = args[2] + elseif cmd == "forpair" and if_on then + for_var2 = args[2] + for_obj = args[3] + for_list = action["get_keys"](for_obj) + vars[for_var2] = for_obj[for_list[1]] + elseif cmd == "for" and if_on then + for_cmdpos = cmdpos + for_type = "number" + for_var = args[1] + for_last = args[3] + for_increment = args[4] or 1 + vars[for_var] = args[2] + skip_for = ((for_increment > 0 and vars[for_var] > for_last) or (for_increment < 0 and vars[for_var] < for_last)) + elseif cmd == "break" and if_on then + if table.remove(args, 1) == "if" then + skip_for = eval(unpack(args)) + else + skip_for = true + end + elseif cmd == "loop" and if_on then + if for_type == "each" then + for_pos = for_pos + 1 + if for_pos <= #for_list then + vars[for_var] = for_list[for_pos] + vars[for_var2] = for_obj[for_list[for_pos]] + cmdpos = for_cmdpos + end + elseif for_type == "number" then + vars[for_var] = vars[for_var] + for_increment + if (for_increment > 0 and vars[for_var] > for_last) or (for_increment < 0 and vars[for_var] < for_last) then + -- quit loop (continue to the next command) + else + cmdpos = for_cmdpos + end + else + cmdpos = 0 + end + + -- return + elseif cmd == "return" and if_on then + return unpack(args) -- or the array itself + elseif if_on then + assert(false, "command not found: " .. cmd) + end + + if if_on and (cmd == "foreach" or cmd == "forpair") then + for_cmdpos = cmdpos + for_type = "each" + for_var = args[1] + for_pos = 1 + vars[for_var] = for_list[1] + skip_for = (for_list[1] == nil) -- if the list is empty or it is a dictionary + end + + if skip_for then + repeat + cmdpos = cmdpos + 1 + call = calls[cmdpos] + until call == nil or call[1] == "loop" + skip_for = false + end + + cmdpos = cmdpos + 1 + end + +end + +function eval(...) + local args = {...} + local v1 = args[1] + local op = args[2] + local v2 = args[3] + local neg = false + local matches = false + if string.sub(op,1,1) == "!" then + neg = true + op = string.sub(op, 2) + end + if v1 == nil and op ~= "=" then + -- does not match + elseif op == "=" then + matches = v1 == v2 + elseif op == ">" then + matches = v1 > v2 + elseif op == ">=" then + matches = v1 >= v2 + elseif op == "<" then + matches = v1 < v2 + elseif op == "<=" then + matches = v1 <= v2 + elseif op == "match" then + matches = string.match(v1, v2) ~= nil + else + assert(false, "operator not known: " .. op) + end + if neg then matches = not matches end + if #args > 3 then + op = args[4] + local matches2 = eval(unpack(args, 5, #args)) + if op == "and" then + return (matches and matches2) + elseif op == "or" then + return (matches or matches2) + else + assert(false, "operator not known: " .. op) + end + end + return matches +end + +function convert_bignum(x, token) + if type(x) ~= 'string' then + x = tostring(x) + end + assert(string.match(x, '[^0-9.]') == nil, "the amount contains invalid character") + local _, count = string.gsub(x, "%.", "") + assert(count <= 1, "the amount is invalid") + if count == 1 then + local num_decimals + if token:lower() == 'aergo' then + num_decimals = 18 + else + num_decimals = contract.call(token, "decimals") + end + assert(num_decimals >= 0 and num_decimals <= 18, "token with invalid decimals") + local p1, p2 = string.match('0' .. x .. '0', '(%d+)%.(%d+)') + local to_add = num_decimals - #p2 + if to_add > 0 then + p2 = p2 .. string.rep('0', to_add) + elseif to_add < 0 then + p2 = string.sub(p2, 1, num_decimals) + end + x = p1 .. p2 + x = string.gsub(x, '0*', '', 1) -- remove leading zeros + if #x == 0 then x = '0' end + end + return bignum.number(x) +end + +abi.register(execute) +` From dca3d141cfb5e1f348a184ec4fcb26b39102e8cc Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sat, 16 Dec 2023 03:12:45 +0000 Subject: [PATCH 17/49] add MULTICALL to aergo-protobuf --- aergo-protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aergo-protobuf b/aergo-protobuf index 0c3579cd4..0ebd3322c 160000 --- a/aergo-protobuf +++ b/aergo-protobuf @@ -1 +1 @@ -Subproject commit 0c3579cd42f830eb787715a78895d971b8ee5fce +Subproject commit 0ebd3322cd33af95a70d24590d7e3a488ac8f01e From 1848b80c795977d21e481d3bd64a1a3e87112410 Mon Sep 17 00:00:00 2001 From: Bernardo Ramos Date: Sun, 17 Dec 2023 16:08:14 -0300 Subject: [PATCH 18/49] aergocli: add multicall command --- cmd/aergocli/cmd/contract.go | 58 +++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/cmd/aergocli/cmd/contract.go b/cmd/aergocli/cmd/contract.go index 010b7f6ac..3d978c64b 100644 --- a/cmd/aergocli/cmd/contract.go +++ b/cmd/aergocli/cmd/contract.go @@ -3,6 +3,7 @@ package cmd import ( "bytes" "context" + "math/big" "encoding/json" "errors" "fmt" @@ -101,6 +102,19 @@ func init() { callCmd.PersistentFlags().BoolVar(&feeDelegation, "delegation", false, "request fee delegation to contract") callCmd.Flags().StringVar(&pw, "password", "", "password (optional, will be asked on the terminal if not given)") + multicallCmd := &cobra.Command{ + Use: `multicall [flags]