55 "fmt"
66 "math"
77 "math/big"
8+ "strings"
89
910 wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
1011 storetypes "github.com/cosmos/cosmos-sdk/store/types"
@@ -27,6 +28,10 @@ var ERC20TransferTopic = common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952
2728var ERC721TransferTopic = common .HexToHash ("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" )
2829var ERC721ApprovalTopic = common .HexToHash ("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925" )
2930var ERC721ApproveAllTopic = common .HexToHash ("0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31" )
31+ var ERC1155TransferSingleTopic = common .HexToHash ("0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62" )
32+ var ERC1155TransferBatchTopic = common .HexToHash ("0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb" )
33+ var ERC1155ApprovalForAllTopic = common .HexToHash ("0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31" )
34+ var ERC1155URITopic = common .HexToHash ("0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b" )
3035var EmptyHash = common .HexToHash ("0x0" )
3136var TrueHash = common .HexToHash ("0x1" )
3237
@@ -94,6 +99,16 @@ func (app *App) AddCosmosEventsToEVMReceiptIfApplicable(ctx sdk.Context, tx sdk.
9499 }
95100 continue
96101 }
102+ // check if there is a ERC1155 pointer to contract Addr
103+ pointerAddr , _ , exists = app .EvmKeeper .GetERC1155CW1155Pointer (ctx , contractAddr )
104+ if exists {
105+ log , eligible := app .translateCW1155Event (ctx , wasmEvent , pointerAddr , contractAddr )
106+ if eligible {
107+ log .Index = uint (len (logs ))
108+ logs = append (logs , log )
109+ }
110+ continue
111+ }
97112 }
98113 if len (logs ) == 0 {
99114 return
@@ -357,6 +372,99 @@ func (app *App) translateCW721Event(ctx sdk.Context, wasmEvent abci.Event, point
357372 return nil , false
358373}
359374
375+ func (app * App ) translateCW1155Event (ctx sdk.Context , wasmEvent abci.Event , pointerAddr common.Address , contractAddr string ) (* ethtypes.Log , bool ) {
376+ action , found := GetAttributeValue (wasmEvent , "action" )
377+ if ! found {
378+ return nil , false
379+ }
380+ var topics []common.Hash
381+ switch action {
382+ case "transfer_single" , "mint_single" , "burn_single" :
383+ fromHash := EmptyHash
384+ toHash := EmptyHash
385+ if action != "mint_single" {
386+ fromHash = app .GetEvmAddressAttribute (ctx , wasmEvent , "owner" )
387+ }
388+ if action != "burn_single" {
389+ toHash = app .GetEvmAddressAttribute (ctx , wasmEvent , "recipient" )
390+ }
391+ topics = []common.Hash {
392+ ERC1155TransferSingleTopic ,
393+ app .GetEvmAddressAttribute (ctx , wasmEvent , "sender" ),
394+ fromHash ,
395+ toHash ,
396+ }
397+ tokenID := GetTokenIDAttribute (wasmEvent )
398+ if tokenID == nil {
399+ return nil , false
400+ }
401+ tokenAmount , found := GetAmountAttribute (wasmEvent )
402+ if ! found {
403+ return nil , false
404+ }
405+ dataHash1 := common .BigToHash (tokenID ).Bytes ()
406+ dataHash2 := common .BigToHash (tokenAmount ).Bytes ()
407+ return & ethtypes.Log {
408+ Address : pointerAddr ,
409+ Topics : topics ,
410+ Data : append (dataHash1 , dataHash2 ... ),
411+ }, true
412+ case "transfer_batch" , "mint_batch" , "burn_batch" :
413+ fromHash := EmptyHash
414+ toHash := EmptyHash
415+ if action != "mint_batch" {
416+ fromHash = app .GetEvmAddressAttribute (ctx , wasmEvent , "owner" )
417+ }
418+ if action != "burn_batch" {
419+ toHash = app .GetEvmAddressAttribute (ctx , wasmEvent , "recipient" )
420+ }
421+ topics = []common.Hash {
422+ ERC1155TransferBatchTopic ,
423+ app .GetEvmAddressAttribute (ctx , wasmEvent , "sender" ),
424+ fromHash ,
425+ toHash ,
426+ }
427+ tokenIDs , found := GetTokenIDsAttribute (wasmEvent )
428+ if ! found {
429+ return nil , false
430+ }
431+ tokenAmounts , found := GetAmountsAttribute (wasmEvent )
432+ if ! found {
433+ return nil , false
434+ }
435+ value := EncodeBigIntArray (tokenIDs )
436+ value = append (value , EncodeBigIntArray (tokenAmounts )... )
437+ return & ethtypes.Log {
438+ Address : pointerAddr ,
439+ Topics : topics ,
440+ Data : value ,
441+ }, true
442+ case "approve_all" :
443+ topics = []common.Hash {
444+ ERC1155ApprovalForAllTopic ,
445+ app .GetEvmAddressAttribute (ctx , wasmEvent , "sender" ),
446+ app .GetEvmAddressAttribute (ctx , wasmEvent , "operator" ),
447+ }
448+ return & ethtypes.Log {
449+ Address : pointerAddr ,
450+ Topics : topics ,
451+ Data : TrueHash .Bytes (),
452+ }, true
453+ case "revoke_all" :
454+ topics = []common.Hash {
455+ ERC1155ApprovalForAllTopic ,
456+ app .GetEvmAddressAttribute (ctx , wasmEvent , "sender" ),
457+ app .GetEvmAddressAttribute (ctx , wasmEvent , "operator" ),
458+ }
459+ return & ethtypes.Log {
460+ Address : pointerAddr ,
461+ Topics : topics ,
462+ Data : EmptyHash .Bytes (),
463+ }, true
464+ }
465+ return nil , false
466+ }
467+
360468func (app * App ) GetEvmAddressAttribute (ctx sdk.Context , event abci.Event , attribute string ) common.Hash {
361469 addrStr , found := GetAttributeValue (event , attribute )
362470 if found {
@@ -398,6 +506,22 @@ func GetAmountAttribute(event abci.Event) (*big.Int, bool) {
398506 return nil , false
399507}
400508
509+ func GetAmountsAttribute (event abci.Event ) ([]* big.Int , bool ) {
510+ results := []* big.Int {}
511+ amounts , found := GetAttributeValue (event , "amounts" )
512+ if ! found {
513+ return results , false
514+ }
515+ for _ , amt := range strings .Split (amounts , "," ) {
516+ amtInt , ok := sdk .NewIntFromString (amt )
517+ if ! ok {
518+ return results , false
519+ }
520+ results = append (results , amtInt .BigInt ())
521+ }
522+ return results , true
523+ }
524+
401525func GetTokenIDAttribute (event abci.Event ) * big.Int {
402526 tokenID , found := GetAttributeValue (event , "token_id" )
403527 if ! found {
@@ -409,3 +533,36 @@ func GetTokenIDAttribute(event abci.Event) *big.Int {
409533 }
410534 return tokenIDInt .BigInt ()
411535}
536+
537+ func GetTokenIDsAttribute (event abci.Event ) ([]* big.Int , bool ) {
538+ results := []* big.Int {}
539+ tokenIDs , found := GetAttributeValue (event , "token_ids" )
540+ if ! found {
541+ return results , false
542+ }
543+ for _ , tid := range strings .Split (tokenIDs , "," ) {
544+ tidInt , ok := sdk .NewIntFromString (tid )
545+ if ! ok {
546+ return results , false
547+ }
548+ results = append (results , tidInt .BigInt ())
549+ }
550+ return results , true
551+ }
552+
553+ func EncodeBigIntArray (inputs []* big.Int ) []byte {
554+ // Arrays are broken up into components:
555+ // - offset byte (always 32)
556+ // - length of array
557+ // - ...array values
558+ offset := big .NewInt (32 )
559+ length := big .NewInt (int64 (len (inputs )))
560+ value := append (
561+ common .BigToHash (offset ).Bytes (),
562+ common .BigToHash (length ).Bytes ()... ,
563+ )
564+ for _ , i := range inputs {
565+ value = append (value , common .BigToHash (i ).Bytes ()... )
566+ }
567+ return value
568+ }
0 commit comments