github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/accounts/abi/event_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package abi 26 27 import ( 28 "bytes" 29 "encoding/hex" 30 "encoding/json" 31 "math/big" 32 "reflect" 33 "strings" 34 "testing" 35 36 "github.com/ethereum/go-ethereum/common" 37 "github.com/ethereum/go-ethereum/crypto" 38 "github.com/stretchr/testify/assert" 39 "github.com/stretchr/testify/require" 40 ) 41 42 var jsonEventTransfer = []byte(`{ 43 "anonymous": false, 44 "inputs": [ 45 { 46 "indexed": true, "name": "from", "type": "address" 47 }, { 48 "indexed": true, "name": "to", "type": "address" 49 }, { 50 "indexed": false, "name": "value", "type": "uint256" 51 }], 52 "name": "Transfer", 53 "type": "event" 54 }`) 55 56 var jsonEventPledge = []byte(`{ 57 "anonymous": false, 58 "inputs": [{ 59 "indexed": false, "name": "who", "type": "address" 60 }, { 61 "indexed": false, "name": "wad", "type": "uint128" 62 }, { 63 "indexed": false, "name": "currency", "type": "bytes3" 64 }], 65 "name": "Pledge", 66 "type": "event" 67 }`) 68 69 var jsonEventMixedCase = []byte(`{ 70 "anonymous": false, 71 "inputs": [{ 72 "indexed": false, "name": "value", "type": "uint256" 73 }, { 74 "indexed": false, "name": "_value", "type": "uint256" 75 }, { 76 "indexed": false, "name": "Value", "type": "uint256" 77 }], 78 "name": "MixedCase", 79 "type": "event" 80 }`) 81 82 //一百万 83 var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240" 84 85 //“0x00CE0D46D924CC8437C806721496599FC3FA268”,2218516807680,“美元” 86 var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000" 87 88 //1000万22185168076801000001 89 var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241" 90 91 func TestEventId(t *testing.T) { 92 var table = []struct { 93 definition string 94 expectations map[string]common.Hash 95 }{ 96 { 97 definition: `[ 98 { "type" : "event", "name" : "balance", "inputs": [{ "name" : "in", "type": "uint256" }] }, 99 { "type" : "event", "name" : "check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] } 100 ]`, 101 expectations: map[string]common.Hash{ 102 "balance": crypto.Keccak256Hash([]byte("balance(uint256)")), 103 "check": crypto.Keccak256Hash([]byte("check(address,uint256)")), 104 }, 105 }, 106 } 107 108 for _, test := range table { 109 abi, err := JSON(strings.NewReader(test.definition)) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 for name, event := range abi.Events { 115 if event.Id() != test.expectations[name] { 116 t.Errorf("expected id to be %x, got %x", test.expectations[name], event.Id()) 117 } 118 } 119 } 120 } 121 122 //TestEventMultiValueWithArrayUnpack验证分析数组后是否将对数组字段进行计数。 123 func TestEventMultiValueWithArrayUnpack(t *testing.T) { 124 definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` 125 type testStruct struct { 126 Value1 [2]uint8 127 Value2 uint8 128 } 129 abi, err := JSON(strings.NewReader(definition)) 130 require.NoError(t, err) 131 var b bytes.Buffer 132 var i uint8 = 1 133 for ; i <= 3; i++ { 134 b.Write(packNum(reflect.ValueOf(i))) 135 } 136 var rst testStruct 137 require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) 138 require.Equal(t, [2]uint8{1, 2}, rst.Value1) 139 require.Equal(t, uint8(3), rst.Value2) 140 } 141 142 func TestEventTupleUnpack(t *testing.T) { 143 144 type EventTransfer struct { 145 Value *big.Int 146 } 147 148 type EventTransferWithTag struct { 149 //这是有效的,因为“value”不可导出, 150 //因此,值只能解编为“value1”。 151 value *big.Int 152 Value1 *big.Int `abi:"value"` 153 } 154 155 type BadEventTransferWithSameFieldAndTag struct { 156 Value *big.Int 157 Value1 *big.Int `abi:"value"` 158 } 159 160 type BadEventTransferWithDuplicatedTag struct { 161 Value1 *big.Int `abi:"value"` 162 Value2 *big.Int `abi:"value"` 163 } 164 165 type BadEventTransferWithEmptyTag struct { 166 Value *big.Int `abi:""` 167 } 168 169 type EventPledge struct { 170 Who common.Address 171 Wad *big.Int 172 Currency [3]byte 173 } 174 175 type BadEventPledge struct { 176 Who string 177 Wad int 178 Currency [3]byte 179 } 180 181 type EventMixedCase struct { 182 Value1 *big.Int `abi:"value"` 183 Value2 *big.Int `abi:"_value"` 184 Value3 *big.Int `abi:"Value"` 185 } 186 187 bigint := new(big.Int) 188 bigintExpected := big.NewInt(1000000) 189 bigintExpected2 := big.NewInt(2218516807680) 190 bigintExpected3 := big.NewInt(1000001) 191 addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268") 192 var testCases = []struct { 193 data string 194 dest interface{} 195 expected interface{} 196 jsonLog []byte 197 error string 198 name string 199 }{{ 200 transferData1, 201 &EventTransfer{}, 202 &EventTransfer{Value: bigintExpected}, 203 jsonEventTransfer, 204 "", 205 "Can unpack ERC20 Transfer event into structure", 206 }, { 207 transferData1, 208 &[]interface{}{&bigint}, 209 &[]interface{}{&bigintExpected}, 210 jsonEventTransfer, 211 "", 212 "Can unpack ERC20 Transfer event into slice", 213 }, { 214 transferData1, 215 &EventTransferWithTag{}, 216 &EventTransferWithTag{Value1: bigintExpected}, 217 jsonEventTransfer, 218 "", 219 "Can unpack ERC20 Transfer event into structure with abi: tag", 220 }, { 221 transferData1, 222 &BadEventTransferWithDuplicatedTag{}, 223 &BadEventTransferWithDuplicatedTag{}, 224 jsonEventTransfer, 225 "struct: abi tag in 'Value2' already mapped", 226 "Can not unpack ERC20 Transfer event with duplicated abi tag", 227 }, { 228 transferData1, 229 &BadEventTransferWithSameFieldAndTag{}, 230 &BadEventTransferWithSameFieldAndTag{}, 231 jsonEventTransfer, 232 "abi: multiple variables maps to the same abi field 'value'", 233 "Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable", 234 }, { 235 transferData1, 236 &BadEventTransferWithEmptyTag{}, 237 &BadEventTransferWithEmptyTag{}, 238 jsonEventTransfer, 239 "struct: abi tag in 'Value' is empty", 240 "Can not unpack ERC20 Transfer event with an empty tag", 241 }, { 242 pledgeData1, 243 &EventPledge{}, 244 &EventPledge{ 245 addr, 246 bigintExpected2, 247 [3]byte{'u', 's', 'd'}}, 248 jsonEventPledge, 249 "", 250 "Can unpack Pledge event into structure", 251 }, { 252 pledgeData1, 253 &[]interface{}{&common.Address{}, &bigint, &[3]byte{}}, 254 &[]interface{}{ 255 &addr, 256 &bigintExpected2, 257 &[3]byte{'u', 's', 'd'}}, 258 jsonEventPledge, 259 "", 260 "Can unpack Pledge event into slice", 261 }, { 262 pledgeData1, 263 &[3]interface{}{&common.Address{}, &bigint, &[3]byte{}}, 264 &[3]interface{}{ 265 &addr, 266 &bigintExpected2, 267 &[3]byte{'u', 's', 'd'}}, 268 jsonEventPledge, 269 "", 270 "Can unpack Pledge event into an array", 271 }, { 272 pledgeData1, 273 &[]interface{}{new(int), 0, 0}, 274 &[]interface{}{}, 275 jsonEventPledge, 276 "abi: cannot unmarshal common.Address in to int", 277 "Can not unpack Pledge event into slice with wrong types", 278 }, { 279 pledgeData1, 280 &BadEventPledge{}, 281 &BadEventPledge{}, 282 jsonEventPledge, 283 "abi: cannot unmarshal common.Address in to string", 284 "Can not unpack Pledge event into struct with wrong filed types", 285 }, { 286 pledgeData1, 287 &[]interface{}{common.Address{}, new(big.Int)}, 288 &[]interface{}{}, 289 jsonEventPledge, 290 "abi: insufficient number of elements in the list/array for unpack, want 3, got 2", 291 "Can not unpack Pledge event into too short slice", 292 }, { 293 pledgeData1, 294 new(map[string]interface{}), 295 &[]interface{}{}, 296 jsonEventPledge, 297 "abi: cannot unmarshal tuple into map[string]interface {}", 298 "Can not unpack Pledge event into map", 299 }, { 300 mixedCaseData1, 301 &EventMixedCase{}, 302 &EventMixedCase{Value1: bigintExpected, Value2: bigintExpected2, Value3: bigintExpected3}, 303 jsonEventMixedCase, 304 "", 305 "Can unpack abi variables with mixed case", 306 }} 307 308 for _, tc := range testCases { 309 assert := assert.New(t) 310 tc := tc 311 t.Run(tc.name, func(t *testing.T) { 312 err := unpackTestEventData(tc.dest, tc.data, tc.jsonLog, assert) 313 if tc.error == "" { 314 assert.Nil(err, "Should be able to unpack event data.") 315 assert.Equal(tc.expected, tc.dest, tc.name) 316 } else { 317 assert.EqualError(err, tc.error, tc.name) 318 } 319 }) 320 } 321 } 322 323 func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, assert *assert.Assertions) error { 324 data, err := hex.DecodeString(hexData) 325 assert.NoError(err, "Hex data should be a correct hex-string") 326 var e Event 327 assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") 328 a := ABI{Events: map[string]Event{"e": e}} 329 return a.Unpack(dest, "e", data) 330 } 331 332 /* 333 取自 334 https://github.com/ethereum/go-ethereum/pull/15568 335 **/ 336 337 338 type testResult struct { 339 Values [2]*big.Int 340 Value1 *big.Int 341 Value2 *big.Int 342 } 343 344 type testCase struct { 345 definition string 346 want testResult 347 } 348 349 func (tc testCase) encoded(intType, arrayType Type) []byte { 350 var b bytes.Buffer 351 if tc.want.Value1 != nil { 352 val, _ := intType.pack(reflect.ValueOf(tc.want.Value1)) 353 b.Write(val) 354 } 355 356 if !reflect.DeepEqual(tc.want.Values, [2]*big.Int{nil, nil}) { 357 val, _ := arrayType.pack(reflect.ValueOf(tc.want.Values)) 358 b.Write(val) 359 } 360 if tc.want.Value2 != nil { 361 val, _ := intType.pack(reflect.ValueOf(tc.want.Value2)) 362 b.Write(val) 363 } 364 return b.Bytes() 365 } 366 367 //TestEventUnpackIndexed验证事件解码器是否将跳过索引字段。 368 func TestEventUnpackIndexed(t *testing.T) { 369 definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` 370 type testStruct struct { 371 Value1 uint8 372 Value2 uint8 373 } 374 abi, err := JSON(strings.NewReader(definition)) 375 require.NoError(t, err) 376 var b bytes.Buffer 377 b.Write(packNum(reflect.ValueOf(uint8(8)))) 378 var rst testStruct 379 require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) 380 require.Equal(t, uint8(0), rst.Value1) 381 require.Equal(t, uint8(8), rst.Value2) 382 } 383 384 //testeventindexedwitharrayunback验证静态数组为索引输入时解码器不会覆盖。 385 func TestEventIndexedWithArrayUnpack(t *testing.T) { 386 definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]` 387 type testStruct struct { 388 Value1 [2]uint8 389 Value2 string 390 } 391 abi, err := JSON(strings.NewReader(definition)) 392 require.NoError(t, err) 393 var b bytes.Buffer 394 stringOut := "abc" 395 //将被编码的字段数*32 396 b.Write(packNum(reflect.ValueOf(32))) 397 b.Write(packNum(reflect.ValueOf(len(stringOut)))) 398 b.Write(common.RightPadBytes([]byte(stringOut), 32)) 399 400 var rst testStruct 401 require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) 402 require.Equal(t, [2]uint8{0, 0}, rst.Value1) 403 require.Equal(t, stringOut, rst.Value2) 404 }