tx · 36fQejUN2YzRW7ooET6swSK1pmxdjwxwfafH8YBAXWyc

3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf:  -0.04300000 Waves

2024.09.19 13:24 [3290416] smart account 3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf > SELF 0.00000000 Waves

{ "type": 13, "id": "36fQejUN2YzRW7ooET6swSK1pmxdjwxwfafH8YBAXWyc", "fee": 4300000, "feeAssetId": null, "timestamp": 1726741448101, "version": 2, "chainId": 84, "sender": "3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf", "senderPublicKey": "62i1XasxLi9NJmrEaq9UaHEGfZaonGKUL6EmFaA7gosh", "proofs": [ "5DHP71DFYdijMx12NxTQxGiuXsR5ZKxVwhua2zUFaK8qP7fcqwhBpBporBxmkiufwQtQyEvVKEH6M9VzDyp7LmPi" ], "script": "base64:CAJACAISBwoFCAgCCAESBwoFCAgCCAESCAoGCAgCAQgBEgYKBAgICAESAwoBCBIAEgMKAQgSBgoECBIBARIECgIIAUoAB0lOVF9NQVgA//////////9/AAVXQVZFUwCAwtcvAAtNSU5fQkFMQU5DRQkAaAIAoJwBBQVXQVZFUwADU0VQAgEsAA9CTE9DS19IQVNIX1NJWkUAIAAUUFVCTElDX0tFWV9IQVNIX1NJWkUAFAAOUk9PVF9IQVNIX1NJWkUAIAAUV0lUSERSQVdfUFJPT0ZTX1NJWkUACgAURVRIX0FERFJFU1NfU1RSX1NJWkUAKAAWTUFYX0NMX1RPX0VMX1RSQU5TRkVSUwAQAAl6ZXJvZXNTdHICgAgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAxhbGxNaW5lcnNLZXkCCWFsbE1pbmVycwAObWFpbkNoYWluSWRLZXkCC21haW5DaGFpbklkAA5sYXN0Q2hhaW5JZEtleQILbGFzdENoYWluSWQAF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AhRmaXJzdFZhbGlkQWx0Q2hhaW5JZAAObWluZXJSZXdhcmRLZXkCC21pbmVyUmV3YXJkAApibG9ja01ldGFLAghibG9ja18weAARZmluYWxpemVkQmxvY2tLZXkCDmZpbmFsaXplZEJsb2NrAAp0b2tlbklkS2V5Agd0b2tlbklkABJlbEJyaWRnZUFkZHJlc3NLZXkCD2VsQnJpZGdlQWRkcmVzcwAXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkCFG5hdGl2ZVRyYW5zZmVyc0NvdW50AQNwYWQBAWkEAXMJAKQDAQUBaQQHJG1hdGNoMAkAsQIBBQFzAwkAAAIAAQUHJG1hdGNoMAkArAICAgcwMDAwMDAwBQFzAwkAAAIAAgUHJG1hdGNoMAkArAICAgYwMDAwMDAFAXMDCQAAAgADBQckbWF0Y2gwCQCsAgICBTAwMDAwBQFzAwkAAAIABAUHJG1hdGNoMAkArAICAgQwMDAwBQFzAwkAAAIABQUHJG1hdGNoMAkArAICAgMwMDAFAXMDCQAAAgAGBQckbWF0Y2gwCQCsAgICAjAwBQFzAwkAAAIABwUHJG1hdGNoMAkArAICAgEwBQFzBQFzARRibG9ja0UyQ1RyYW5zZmVyc0tleQEMYmxvY2tIYXNoSGV4CQCsAgICEmVsVG9DbFRyYW5zZmVyc18weAUMYmxvY2tIYXNoSGV4AQxlcG9jaE1ldGFLZXkBBWVwb2NoCQCsAgICBmVwb2NoXwkBA3BhZAEFBWVwb2NoARRjaGFpbkZpcnN0QmxvY2tJZEtleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCCkZpcnN0QmxvY2sBDGNoYWluTWV0YUtleQEHY2hhaW5JZAkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkARJjaGFpbkxhc3RIZWlnaHRLZXkCB2NoYWluSWQFbWluZXIJAKwCAgkArAICCQCsAgICBmNoYWluXwkBA3BhZAEFB2NoYWluSWQCAV8JAKUIAQUFbWluZXIBFGNoYWluRm9ya2VkSGVpZ2h0S2V5AQdjaGFpbklkCQCsAgIJAKwCAgIGY2hhaW5fCQEDcGFkAQUHY2hhaW5JZAIMRm9ya2VkSGVpZ2h0AQ1zdXBwb3J0ZXJzS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKU3VwcG9ydGVycwEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQltaW5lckFkZHIJAKwCAgkArAICAgZtaW5lcl8FCW1pbmVyQWRkcgIOX1Jld2FyZEFkZHJlc3MBCm1pbmVyUGtLZXkBDXJld2FyZEFkZHJlc3MJAKwCAgkArAICAghtaW5lcl8weAUNcmV3YXJkQWRkcmVzcwIDX1BLAQ9taW5lckNoYWluSWRLZXkBBW1pbmVyCQCsAgIJAKwCAgIGbWluZXJfCQClCAEFBW1pbmVyAghfQ2hhaW5JZAAUbmF0aXZlVHJhbnNmZXJzQ291bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkAAAERbmF0aXZlVHJhbnNmZXJLZXkBBWluZGV4CQCsAgICD25hdGl2ZVRyYW5zZmVyXwkApAMBBQVpbmRleAEVbWtOYXRpdmVUcmFuc2ZlckVudHJ5AwVpbmRleBBkZXN0RWxBZGRyZXNzSGV4BmFtb3VudAkBC1N0cmluZ0VudHJ5AgkBEW5hdGl2ZVRyYW5zZmVyS2V5AQUFaW5kZXgJAKwCAgkArAICCQCsAgICAjB4BRBkZXN0RWxBZGRyZXNzSGV4BQNTRVAJAKQDAQUGYW1vdW50ARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAxByZWZUcmFuc2ZlckluZGV4DXRyYW5zZmVySW5kZXgMZXhwZWN0UmV3YXJkBAxtYXhUcmFuc2ZlcnMDBQxleHBlY3RSZXdhcmQJAGUCBRZNQVhfQ0xfVE9fRUxfVFJBTlNGRVJTAAEFFk1BWF9DTF9UT19FTF9UUkFOU0ZFUlMED2FjdHVhbFRyYW5zZmVycwkAZQIFDXRyYW5zZmVySW5kZXgFEHJlZlRyYW5zZmVySW5kZXgEC2NoZWNrTnVtYmVyAwkAZgIFD2FjdHVhbFRyYW5zZmVycwUMbWF4VHJhbnNmZXJzCQACAQkArAICCQCsAgIJAKwCAgINQWxsb3dlZCBvbmx5IAkApAMBBQxtYXhUcmFuc2ZlcnMCECB0cmFuc2ZlcnMsIGdvdCAJAKQDAQUPYWN0dWFsVHJhbnNmZXJzBgMJAAACBQtjaGVja051bWJlcgULY2hlY2tOdW1iZXIDCQBnAgUNdHJhbnNmZXJJbmRleAUUbmF0aXZlVHJhbnNmZXJzQ291bnQJAAIBCQCsAgIJAKwCAgkArAICAhVBdHRlbXB0IHRvIHRyYW5zZmVyICMJAKQDAQUNdHJhbnNmZXJJbmRleAIXLiBBdmFpbGFibGUgdHJhbnNmZXJzOiAJAKQDAQUUbmF0aXZlVHJhbnNmZXJzQ291bnQGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQphbW91bnRHdEVxAwF0BGd0RXEJcXVldWVTaXplAwkAZwIIBQF0BmFtb3VudAUEZ3RFcQYJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhRUcmFuc2ZlcnJpbmcgYW1vdW50IAkApAMBCAUBdAZhbW91bnQCDiBzaG91bGQgYmUgPj0gCQCkAwEFBGd0RXECEyBmb3IgcXVldWUgc2l6ZSBvZiAJAKQDAQUJcXVldWVTaXplAhcuIFRyYW5zZmVyIG1vcmUgb3Igd2FpdAERZ2VuZXJhdGluZ0JhbGFuY2UBB2FkZHJlc3MICQDvBwEFB2FkZHJlc3MKZ2VuZXJhdGluZwEJY2hhaW5NZXRhAQdjaGFpbklkBAFzCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEMY2hhaW5NZXRhS2V5AQUHY2hhaW5JZAQFaXRlbXMJALUJAgUBcwUDU0VQCQCUCgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVpdGVtcwAACQCRAwIFBWl0ZW1zAAEBEG1rQ2hhaW5NZXRhRW50cnkDB2NoYWluSWQObmV3Q2hhaW5IZWlnaHQMYmxvY2tIYXNoSGV4CQELU3RyaW5nRW50cnkCCQEMY2hhaW5NZXRhS2V5AQUHY2hhaW5JZAkArAICCQCsAgIJAKQDAQUObmV3Q2hhaW5IZWlnaHQFA1NFUAUMYmxvY2tIYXNoSGV4AAttYWluQ2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5tYWluQ2hhaW5JZEtleQAAAAskdDA1MDI5NTA5NQkBCWNoYWluTWV0YQEFC21haW5DaGFpbklkAA9tYWluQ2hhaW5IZWlnaHQIBQskdDA1MDI5NTA5NQJfMQASbWFpbkNoYWluTGFzdEJsb2NrCAULJHQwNTAyOTUwOTUCXzIBCWVwb2NoTWV0YQEFZXBvY2gEByRtYXRjaDAJAKIIAQkBDGVwb2NoTWV0YUtleQEFBWVwb2NoAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAQJZnJhZ21lbnRzCQC1CQIFAXMFA1NFUAkAlQoDCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCWZyYWdtZW50cwAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZnJhZ21lbnRzAAEJAJEDAgUJZnJhZ21lbnRzAAIFBHVuaXQACyR0MDUzMjY1NDUwBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACFihBZGRyZXNzLCBJbnQsIFN0cmluZykEAW0FByRtYXRjaDAFAW0JAJQKAgUEdW5pdAAAAA50aGlzRXBvY2hNaW5lcggFCyR0MDUzMjY1NDUwAl8xAAx0aGlzRXBvY2hSZWYIBQskdDA1MzI2NTQ1MAJfMgAMYWxsTWluZXJzU3RyCQELdmFsdWVPckVsc2UCCQCiCAEFDGFsbE1pbmVyc0tleQIAAAlhbGxNaW5lcnMEByRtYXRjaDAFDGFsbE1pbmVyc1N0cgMJAAACAgAFByRtYXRjaDAFA25pbAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3JhdwUHJG1hdGNoMAkAvAkCBQNyYXcFA1NFUAkAAgECC01hdGNoIGVycm9yAQlibG9ja01ldGEBB2Jsb2NrSWQEBG1ldGEJARFAZXh0ck5hdGl2ZSgxMDU3KQEJAKwCAgUKYmxvY2tNZXRhSwUHYmxvY2tJZAQIbWV0YVNpemUJAMgBAQUEbWV0YQQLYmxvY2tIZWlnaHQJALEJAQUEbWV0YQQKYmxvY2tFcG9jaAkAsgkCBQRtZXRhAAgEC2Jsb2NrUGFyZW50CQDJAQIJAMoBAgUEbWV0YQAQBQ9CTE9DS19IQVNIX1NJWkUEB2NoYWluSWQJALIJAgUEbWV0YQkAZAIAEAUPQkxPQ0tfSEFTSF9TSVpFBApiYXNlT2Zmc2V0CQBkAgAYBQ9CTE9DS19IQVNIX1NJWkUEDnJlbWFpbmluZ0J5dGVzCQBlAgUIbWV0YVNpemUFCmJhc2VPZmZzZXQEFGUyY1RyYW5zZmVyc1Jvb3RIYXNoAwkAZwIFDnJlbWFpbmluZ0J5dGVzBQ5ST09UX0hBU0hfU0laRQkAyQECCQDKAQIFBG1ldGEFCmJhc2VPZmZzZXQFDlJPT1RfSEFTSF9TSVpFAQAEFGxhc3RDMkVUcmFuc2ZlckluZGV4AwMJAAACBQ5yZW1haW5pbmdCeXRlcwAIBgkAZgIFDnJlbWFpbmluZ0J5dGVzBQ5ST09UX0hBU0hfU0laRQkAsgkCBQRtZXRhCQBkAgUKYmFzZU9mZnNldAkAyAEBBRRlMmNUcmFuc2ZlcnNSb290SGFzaAD///////////8BCQCYCgYFC2Jsb2NrSGVpZ2h0BQpibG9ja0Vwb2NoBQtibG9ja1BhcmVudAUHY2hhaW5JZAUUZTJjVHJhbnNmZXJzUm9vdEhhc2gFFGxhc3RDMkVUcmFuc2ZlckluZGV4ARBta0Jsb2NrTWV0YUVudHJ5BgxibG9ja0hhc2hIZXgLYmxvY2tIZWlnaHQOYmxvY2tQYXJlbnRIZXgHY2hhaW5JZBdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQZZTJjVHJhbnNmZXJzUm9vdEhhc2hCeXRlcwkA3QQBBRdlMmNUcmFuc2ZlcnNSb290SGFzaEhleAQRcm9vdEhhc2hCeXRlc1NpemUJAMgBAQUZZTJjVHJhbnNmZXJzUm9vdEhhc2hCeXRlcwQNY2hlY2tSb290SGFzaAMDCQAAAgURcm9vdEhhc2hCeXRlc1NpemUAAAYJAAACBRFyb290SGFzaEJ5dGVzU2l6ZQUOUk9PVF9IQVNIX1NJWkUGCQACAQkArAICCQCsAgIJAKwCAgIlVHJhbnNmZXJzIHJvb3QgaGFzaCBzaG91bGQgaGF2ZSAwIG9yIAkApAMBBQ5ST09UX0hBU0hfU0laRQIMIGJ5dGVzLCBnb3QgCQCkAwEFEXJvb3RIYXNoQnl0ZXNTaXplAwkAAAIFDWNoZWNrUm9vdEhhc2gFDWNoZWNrUm9vdEhhc2gEDmJsb2NrTWV0YUJ5dGVzCQDLAQIJAMsBAgkAywECCQDLAQIJAMsBAgkAmgMBBQtibG9ja0hlaWdodAkAmgMBBQZoZWlnaHQJAN0EAQUOYmxvY2tQYXJlbnRIZXgJAJoDAQUHY2hhaW5JZAUZZTJjVHJhbnNmZXJzUm9vdEhhc2hCeXRlcwkAmgMBBRRsYXN0QzJFVHJhbnNmZXJJbmRleAkBC0JpbmFyeUVudHJ5AgkArAICBQpibG9ja01ldGFLBQxibG9ja0hhc2hIZXgFDmJsb2NrTWV0YUJ5dGVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQxsYXN0SGVpZ2h0QnkCBW1pbmVyB2NoYWluSWQEByRtYXRjaDAJAJ8IAQkBEmNoYWluTGFzdEhlaWdodEtleQIFB2NoYWluSWQFBW1pbmVyAwkAAQIFByRtYXRjaDACA0ludAQBaAUHJG1hdGNoMAUBaAQJYmxvY2tIYXNoCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgtMYXN0TWluZWRCeQkApQgBBQVtaW5lcggJAQlibG9ja01ldGEBBQlibG9ja0hhc2gCXzEACyR0MDc0OTA4NDI1BAloaXRTb3VyY2UEByRtYXRjaDAIBQlsYXN0QmxvY2sDdnJmAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEA3ZyZgUHJG1hdGNoMAUDdnJmCAUJbGFzdEJsb2NrE2dlbmVyYXRpb25TaWduYXR1cmUKAQxwcm9jZXNzTWluZXICBHByZXYFbWluZXIECyR0MDc3NTc3ODIwBQRwcmV2BAlwcmV2TWluZXIIBQskdDA3NzU3NzgyMAJfMQQQcHJldlRvdGFsQmFsYW5jZQgFCyR0MDc3NTc3ODIwAl8yBAlwcmV2RGVsYXkIBQskdDA3NzU3NzgyMAJfMwQKcHJldk1pbmVycwgFCyR0MDc3NTc3ODIwAl80BAxtaW5lckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBW1pbmVyBA93YXZlc0dlbkJhbGFuY2UICQDvBwEFDG1pbmVyQWRkcmVzcwpnZW5lcmF0aW5nBAxtaW5lckJhbGFuY2UJARFnZW5lcmF0aW5nQmFsYW5jZQEFDG1pbmVyQWRkcmVzcwMDCQBmAgULTUlOX0JBTEFOQ0UFD3dhdmVzR2VuQmFsYW5jZQYJAGcCAAAFDG1pbmVyQmFsYW5jZQUEcHJldgQJbmV4dERlbGF5CQCFBwIFDG1pbmVyQWRkcmVzcwUMbWluZXJCYWxhbmNlAwkAZgIFCXByZXZEZWxheQUJbmV4dERlbGF5CQCWCgQFBW1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlBQluZXh0RGVsYXkJAM0IAgUKcHJldk1pbmVycwUFbWluZXIJAJYKBAUJcHJldk1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlBQlwcmV2RGVsYXkJAM0IAgUKcHJldk1pbmVycwUFbWluZXIKAAIkbAUJYWxsTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEAgAAAAUHSU5UX01BWAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQxwcm9jZXNzTWluZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgARY29tcHV0ZWRHZW5lcmF0b3IIBQskdDA3NDkwODQyNQJfMQAUY29tcHV0ZWRUb3RhbEJhbGFuY2UIBQskdDA3NDkwODQyNQJfMgALJHQwODQyNzg0OTMJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sADG1jbGJJZ25vcmVkMQgFCyR0MDg0Mjc4NDkzAl8xAA5tYWluQ2hhaW5FcG9jaAgFCyR0MDg0Mjc4NDkzAl8yARtjYWxjdWxhdGVGaW5hbGl6ZWRCbG9ja0hhc2gDCGN1ck1pbmVyDGN1clByZXZFcG9jaBBjdXJMYXN0QmxvY2tIYXNoBAtvZmZzZXRzXzEwMAkAvAkCAmQ6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6AgAEC2hhbGZCYWxhbmNlCQBpAgUUY29tcHV0ZWRUb3RhbEJhbGFuY2UAAgoBBHN0ZXACBHByZXYEbmV4dAQLJHQwODg1OTg5MjMFBHByZXYECXRoaXNFcG9jaAgFCyR0MDg4NTk4OTIzAl8xBA5tYXliZVNhZmVFcG9jaAgFCyR0MDg4NTk4OTIzAl8yBAx0b3RhbEJhbGFuY2UIBQskdDA4ODU5ODkyMwJfMwQKcHJldk1pbmVycwgFCyR0MDg4NTk4OTIzAl80BAckbWF0Y2gwBQ5tYXliZVNhZmVFcG9jaAMJAAECBQckbWF0Y2gwAgRVbml0BAskdDA4OTgxOTE0NwMJAAACBQl0aGlzRXBvY2gFBmhlaWdodAkAlQoDBQhjdXJNaW5lcgUMY3VyUHJldkVwb2NoBRBjdXJMYXN0QmxvY2tIYXNoCQEFdmFsdWUBCQEJZXBvY2hNZXRhAQUJdGhpc0Vwb2NoBAVtaW5lcggFCyR0MDg5ODE5MTQ3Al8xBAlwcmV2RXBvY2gIBQskdDA4OTgxOTE0NwJfMgQNbGFzdEJsb2NrSGFzaAgFCyR0MDg5ODE5MTQ3Al8zAwMJAAACBQlwcmV2RXBvY2gAAAYJAGcCCQBlAgUGaGVpZ2h0BQl0aGlzRXBvY2gAZAkAlgoEBQl0aGlzRXBvY2gFDWxhc3RCbG9ja0hhc2gFDHRvdGFsQmFsYW5jZQUJYWxsTWluZXJzBAskdDA5MzAxOTUwMwMJAQ9jb250YWluc0VsZW1lbnQCBQpwcmV2TWluZXJzBQVtaW5lcgkAlAoCBQx0b3RhbEJhbGFuY2UFCnByZXZNaW5lcnMJAJQKAgkAZAIFDHRvdGFsQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUFbWluZXIJAMwIAgUFbWluZXIFCnByZXZNaW5lcnMED25ld1RvdGFsQmFsYW5jZQgFCyR0MDkzMDE5NTAzAl8xBAluZXdNaW5lcnMIBQskdDA5MzAxOTUwMwJfMgMJAGYCBQ9uZXdUb3RhbEJhbGFuY2UFC2hhbGZCYWxhbmNlCQCW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IGFsbG93ZWQgdG8gbWluZSBpbiAJAKQDAQUGaGVpZ2h0AhEgZXBvY2guIEV4cGVjdGVkIAURY29tcHV0ZWRHZW5lcmF0b3IFBHVuaXQBEmlzUmVmZXJlbmNlQ29ycmVjdAIJcmVmZXJlbmNlCWxhc3RCbG9jawMJAAACBQlyZWZlcmVuY2UFCWxhc3RCbG9jawUEdW5pdAkAAgEJAKwCAgkArAICCQCsAgICMEV4cGVjdGVkIGEgcmVmZXJlbmNlIHRvIHRoZSBjaGFpbiBsYXN0IGJsb2NrOiAweAUJbGFzdEJsb2NrAgkuIEdvdDogMHgFCXJlZmVyZW5jZQEPY2hhaW5Jc0luYWN0aXZlAQdjaGFpbklkBAxmaXJzdEJsb2NrSWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFB2NoYWluSWQEFGZpcnN0VmFsaWRBbHRDaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AAADCQBmAgUUZmlyc3RWYWxpZEFsdENoYWluSWQFB2NoYWluSWQGCQBmAggJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMQgJAQlibG9ja01ldGEBBQxmaXJzdEJsb2NrSWQCXzEBDG1pbmVyQ2hhaW5JZAEFbWluZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBD21pbmVyQ2hhaW5JZEtleQEFBW1pbmVyCQCfCAEJAKwCAgIJY2hhaW5JZE9mCQClCAEFBW1pbmVyAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMJZ2VuZXJhdG9yD2V4cGVjdGVkQ2hhaW5JZBBjaGVja0hlaWdodEJsb2NrBA9oZWlnaHRJc0NvcnJlY3QEByRtYXRjaDAFEGNoZWNrSGVpZ2h0QmxvY2sDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAlibG9ja0hhc2gFByRtYXRjaDAEFGxhc3RNaW5lZEJsb2NrSGVpZ2h0CQEMbGFzdEhlaWdodEJ5AgUJZ2VuZXJhdG9yBQttYWluQ2hhaW5JZAkAZgIJAGQCCAkBCWJsb2NrTWV0YQEFCWJsb2NrSGFzaAJfMQABBRRsYXN0TWluZWRCbG9ja0hlaWdodAYEByRtYXRjaDAJAQxtaW5lckNoYWluSWQBBQlnZW5lcmF0b3IDCQABAgUHJG1hdGNoMAIDSW50BAljdXJyZW50SWQFByRtYXRjaDADAwkAAAIFCWN1cnJlbnRJZAUPZXhwZWN0ZWRDaGFpbklkBgMJAQ9jaGFpbklzSW5hY3RpdmUBBQljdXJyZW50SWQFD2hlaWdodElzQ29ycmVjdAcFBHVuaXQJAAIBCQCsAgICHG1pbmVyIGlzIG1pbmluZyBvdGhlciBjaGFpbiAJAKQDAQUJY3VycmVudElkBQR1bml0AAxoZWlnaHRTdHJpbmcJAKwCAgILIGF0IGhlaWdodCAJAKQDAQUGaGVpZ2h0AQV2cmZBdAEGaGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAO0HAQUGaGVpZ2h0CQCsAgICG2xhc3QgYmxvY2sgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nA3ZyZgkArAICAhRWUkYgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nARJlbnN1cmVDb3JyZWN0RXBvY2gBC2V4cGVjdGVkVlJGBAlhY3R1YWxWUkYJAQV2cmZBdAEFBmhlaWdodAMJAAACBQtleHBlY3RlZFZSRgUJYWN0dWFsVlJGBQR1bml0CQACAQkArAICCQCsAgIJAKwCAgkArAICAg1FeHBlY3RlZCBWUkYgCQDYBAEFC2V4cGVjdGVkVlJGAhcgZG9lcyBub3QgbWF0Y2ggYWN0dWFsIAkA2AQBBQlhY3R1YWxWUkYFDGhlaWdodFN0cmluZwEMYWRkU3VwcG9ydGVyAgdjaGFpbklkCWdlbmVyYXRvcgQNc3VwcG9ydGVyc1N0cgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDXN1cHBvcnRlcnNLZXkBBQdjaGFpbklkBApzdXBwb3J0ZXJzCQC8CQIFDXN1cHBvcnRlcnNTdHIFA1NFUAMJAQ9jb250YWluc0VsZW1lbnQCBQpzdXBwb3J0ZXJzCQClCAEFCWdlbmVyYXRvcgUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAkArAICCQCsAgIFDXN1cHBvcnRlcnNTdHIFA1NFUAkApQgBBQlnZW5lcmF0b3IFA25pbAEJc2V0T3JGYWlsAgVmbGFncwVpbmRleAMJAGYCAAAFBWluZGV4CQACAQkArAICAiJDYW4ndCB3aXRoZHJhdyBhdCBuZWdhdGl2ZSBpbmRleDogCQCkAwEFBWluZGV4BAlmbGFnc1NpemUJALECAQUFZmxhZ3MDCQBnAgUFaW5kZXgFCWZsYWdzU2l6ZQQJYWRkWmVyb2VzCQBlAgUFaW5kZXgFCWZsYWdzU2l6ZQMJAGYCBQlhZGRaZXJvZXMJALECAQUJemVyb2VzU3RyCQACAQkArAICCQCsAgICCkNhbid0IGFkZCAJAKQDAQUJYWRkWmVyb2VzAiUgZW1wdHkgZmxhZ3MuIENvbnRhY3Qgd2l0aCBkZXZlbG9wZXJzCQCsAgIJAKwCAgUFZmxhZ3MJAK8CAgUJemVyb2VzU3RyBQlhZGRaZXJvZXMCATEEBHRhaWwJALACAgUFZmxhZ3MFBWluZGV4BAdhdEluZGV4CQCvAgIFBHRhaWwAAQMJAAACBQdhdEluZGV4AgEwCQCsAgIJAKwCAgkArwICBQVmbGFncwUFaW5kZXgCATEJALACAgUEdGFpbAABCQACAQkArAICCQCsAgICClRyYW5zZmVyICMJAKQDAQUFaW5kZXgCFyBoYXMgYmVlbiBhbHJlYWR5IHRha2VuARF2YWxpZGF0ZUJsb2NrSGFzaAEGaGV4U3RyBAxkZWNvZGVkQnl0ZXMJAN0EAQUGaGV4U3RyAwkBAiE9AgkAyAEBBQxkZWNvZGVkQnl0ZXMFD0JMT0NLX0hBU0hfU0laRQkAAgECF2ludmFsaWQgYmxvY2sgaWQgbGVuZ3RoBQZoZXhTdHIBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwZjYWxsZXIPbmV3QmxvY2tIYXNoSGV4CXByZXZFcG9jaAQXY3VyRmluYWxpemVkQmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzEEFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAkBG2NhbGN1bGF0ZUZpbmFsaXplZEJsb2NrSGFzaAMFBmNhbGxlcgUJcHJldkVwb2NoBQ9uZXdCbG9ja0hhc2hIZXgDAwkAAAIFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAUPbmV3QmxvY2tIYXNoSGV4BgkAZgIICQEJYmxvY2tNZXRhAQUVbmV3RmluYWxpemVkQmxvY2tIYXNoAl8xBRdjdXJGaW5hbGl6ZWRCbG9ja0hlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCBRFmaW5hbGl6ZWRCbG9ja0tleQUVbmV3RmluYWxpemVkQmxvY2tIYXNoBQNuaWwFA25pbAkBaQEPZXh0ZW5kTWFpbkNoYWluBQxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4A3ZyZhdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQN2cmYDCQAAAgUKY2hlY2tFcG9jaAUKY2hlY2tFcG9jaAQKY2hlY2tDaGFpbgkBHWVuc3VyZUV4cGVjdGVkT3JJbmFjdGl2ZUNoYWluAwgFAWkMb3JpZ2luQ2FsbGVyBQttYWluQ2hhaW5JZAUEdW5pdAMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBA5jaGVja1JlZmVyZW5jZQkBEmlzUmVmZXJlbmNlQ29ycmVjdAIFDHJlZmVyZW5jZUhleAUSbWFpbkNoYWluTGFzdEJsb2NrAwkAAAIFDmNoZWNrUmVmZXJlbmNlBQ5jaGVja1JlZmVyZW5jZQQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzYFFGxhc3RDMkVUcmFuc2ZlckluZGV4BgMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMEDXRoaXNFcG9jaE1ldGEEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIEVW5pdAkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKwCAgkArAICCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUDU0VQCQCkAwEFDm1haW5DaGFpbkVwb2NoBQNTRVAFDGJsb2NrSGFzaEhleAQFb3RoZXIFByRtYXRjaDAJAAIBAhVFcG9jaCBhbHJlYWR5IHN0YXJ0ZWQDCQAAAgUNdGhpc0Vwb2NoTWV0YQUNdGhpc0Vwb2NoTWV0YQQOY2hlY2tHZW5lcmF0b3IJARFlbnN1cmVNaW5pbmdFcG9jaAEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQ5jaGVja0dlbmVyYXRvcgUOY2hlY2tHZW5lcmF0b3IEFHVwZGF0ZUZpbmFsaXplZEJsb2NrCQEdZ2V0VXBkYXRlRmluYWxpemVkQmxvY2tBY3Rpb24DCAUBaQxvcmlnaW5DYWxsZXIFDGJsb2NrSGFzaEhleAUObWFpbkNoYWluRXBvY2gEDm5ld0NoYWluSGVpZ2h0CQBkAgUPbWFpbkNoYWluSGVpZ2h0AAEJAM4IAgkAzAgCCQEQbWtCbG9ja01ldGFFbnRyeQYFDGJsb2NrSGFzaEhleAUObmV3Q2hhaW5IZWlnaHQFEm1haW5DaGFpbkxhc3RCbG9jawULbWFpbkNoYWluSWQFF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4BRRsYXN0QzJFVHJhbnNmZXJJbmRleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFC21haW5DaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQttYWluQ2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFC21haW5DaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIFDXRoaXNFcG9jaE1ldGEFA25pbAUUdXBkYXRlRmluYWxpemVkQmxvY2sJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENc3RhcnRBbHRDaGFpbgUMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAN2cmYXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgUbGFzdEMyRVRyYW5zZmVySW5kZXgEDmNoZWNrQmxvY2tIYXNoCQERdmFsaWRhdGVCbG9ja0hhc2gBBQxibG9ja0hhc2hIZXgDCQAAAgUOY2hlY2tCbG9ja0hhc2gFDmNoZWNrQmxvY2tIYXNoBApjaGVja0Vwb2NoCQESZW5zdXJlQ29ycmVjdEVwb2NoAQUDdnJmAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gEDSR0MDE2MTMyMTYyNDUJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgEDnJlZkNoYWluSGVpZ2h0CAUNJHQwMTYxMzIxNjI0NQJfMQQIcmVmRXBvY2gIBQ0kdDAxNjEzMjE2MjQ1Al8yBAtyZWZJZ25vcmVkMQgFDSR0MDE2MTMyMTYyNDUCXzMEC3JlZklnbm9yZWQyCAUNJHQwMTYxMzIxNjI0NQJfNAQLcmVmSWdub3JlZDMIBQ0kdDAxNjEzMjE2MjQ1Al81BBByZWZUcmFuc2ZlckluZGV4CAUNJHQwMTYxMzIxNjI0NQJfNgQOZmluYWxpemVkRXBvY2gICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzIECGVwb2NoUmVmAwkAZwIFCHJlZkVwb2NoBQ5maW5hbGl6ZWRFcG9jaAUIcmVmRXBvY2gJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICI0NhbiBub3Qgc3RhcnQgYWx0IGNoYWluIGZyb20gZXBvY2ggCQCkAwEFCHJlZkVwb2NoAggsIGVwb2NoIAkApAMBBQ5maW5hbGl6ZWRFcG9jaAINIGlzIGZpbmFsaXplZAQKY2hlY2tDaGFpbgkBHWVuc3VyZUV4cGVjdGVkT3JJbmFjdGl2ZUNoYWluAwgFAWkMb3JpZ2luQ2FsbGVyBQttYWluQ2hhaW5JZAUMcmVmZXJlbmNlSGV4AwkAAAIFCmNoZWNrQ2hhaW4FCmNoZWNrQ2hhaW4EDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMFEHJlZlRyYW5zZmVySW5kZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4BgMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMECm5ld0NoYWluSWQJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFDmxhc3RDaGFpbklkS2V5AAAAAQQObmV3Q2hhaW5IZWlnaHQJAGQCBQ5yZWZDaGFpbkhlaWdodAABBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQhlcG9jaFJlZgUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgkAzAgCBQ10aGlzRXBvY2hNZXRhCQDMCAIJARBta0Jsb2NrTWV0YUVudHJ5BgUMYmxvY2tIYXNoSGV4BQ5uZXdDaGFpbkhlaWdodAUMcmVmZXJlbmNlSGV4BQpuZXdDaGFpbklkBRdlMmNUcmFuc2ZlcnNSb290SGFzaEhleAUUbGFzdEMyRVRyYW5zZmVySW5kZXgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQUKbmV3Q2hhaW5JZAUMYmxvY2tIYXNoSGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUKbmV3Q2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD21pbmVyQ2hhaW5JZEtleQEIBQFpDG9yaWdpbkNhbGxlcgUKbmV3Q2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFCm5ld0NoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQttYWluQ2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCCQENc3VwcG9ydGVyc0tleQEFCm5ld0NoYWluSWQJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5sYXN0Q2hhaW5JZEtleQUKbmV3Q2hhaW5JZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmV4dGVuZEFsdENoYWluBgxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4A3ZyZgdjaGFpbklkF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFA3ZyZgMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBBNjaGFpbkZpcnN0QmxvY2tNZXRhCQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAQKY2hlY2tDaGFpbgkBHWVuc3VyZUV4cGVjdGVkT3JJbmFjdGl2ZUNoYWluAwgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkCQDcBAEIBRNjaGFpbkZpcnN0QmxvY2tNZXRhAl8zAwkAAAIFCmNoZWNrQ2hhaW4FCmNoZWNrQ2hhaW4EDSR0MDE4NTU4MTg2MTIJAQljaGFpbk1ldGEBBQdjaGFpbklkBAtjaGFpbkhlaWdodAgFDSR0MDE4NTU4MTg2MTICXzEEDmNoYWluTGFzdEJsb2NrCAUNJHQwMTg1NTgxODYxMgJfMgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFDmNoYWluTGFzdEJsb2NrAwkAAAIFDmNoZWNrUmVmZXJlbmNlBQ5jaGVja1JlZmVyZW5jZQQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzYFFGxhc3RDMkVUcmFuc2ZlckluZGV4BgMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMEDm5ld0NoYWluSGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQJcHJldkVwb2NoCAkBCWJsb2NrTWV0YQEFDHJlZmVyZW5jZUhleAJfMgQTdXBkYXRlTWFpbkNoYWluRGF0YQMJAGYCCQERc3VwcG9ydGluZ0JhbGFuY2UBBQdjaGFpbklkCQBpAgUUY29tcHV0ZWRUb3RhbEJhbGFuY2UAAgQLbGFzdENoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObGFzdENoYWluSWRLZXkAAAQUdXBkYXRlRmluYWxpemVkQmxvY2sJAR1nZXRVcGRhdGVGaW5hbGl6ZWRCbG9ja0FjdGlvbgMIBQFpDG9yaWdpbkNhbGxlcgUMYmxvY2tIYXNoSGV4BQlwcmV2RXBvY2gJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGNoYWluRm9ya2VkSGVpZ2h0S2V5AQULbWFpbkNoYWluSWQIBRNjaGFpbkZpcnN0QmxvY2tNZXRhAl8xCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5tYWluQ2hhaW5JZEtleQUHY2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXZmlyc3RWYWxpZEFsdENoYWluSWRLZXkJAGQCBQtsYXN0Q2hhaW5JZAABBQNuaWwFFHVwZGF0ZUZpbmFsaXplZEJsb2NrBQNuaWwEDXRoaXNFcG9jaE1ldGEEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIEVW5pdAkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKwCAgkArAICCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUDU0VQCQCkAwEFCXByZXZFcG9jaAUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkAwkAAAIFDXRoaXNFcG9jaE1ldGEFDXRoaXNFcG9jaE1ldGEEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBB11cGRhdGVNYWluQ2hhaW5MYXN0TWluZWRCbG9jawMDCQAAAgUTdXBkYXRlTWFpbkNoYWluRGF0YQUDbmlsCQECIT0CCQELdmFsdWVPckVsc2UCCQEMbWluZXJDaGFpbklkAQgFAWkMb3JpZ2luQ2FsbGVyAAAFB2NoYWluSWQHCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgULbWFpbkNoYWluSWQIBQFpDG9yaWdpbkNhbGxlcggFE2NoYWluRmlyc3RCbG9ja01ldGECXzEFA25pbAUDbmlsCQDOCAIJAM4IAgkAzggCCQDMCAIJARBta0Jsb2NrTWV0YUVudHJ5BgUMYmxvY2tIYXNoSGV4BQ5uZXdDaGFpbkhlaWdodAUMcmVmZXJlbmNlSGV4BQdjaGFpbklkBRdlMmNUcmFuc2ZlcnNSb290SGFzaEhleAUUbGFzdEMyRVRyYW5zZmVySW5kZXgJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDBQdjaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIFDXRoaXNFcG9jaE1ldGEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9taW5lckNoYWluSWRLZXkBCAUBaQxvcmlnaW5DYWxsZXIFB2NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQdjaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0BQNuaWwFE3VwZGF0ZU1haW5DaGFpbkRhdGEJAQxhZGRTdXBwb3J0ZXICBQdjaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFHXVwZGF0ZU1haW5DaGFpbkxhc3RNaW5lZEJsb2NrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC2FwcGVuZEJsb2NrBAxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4F2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BAtjaGVja0NhbGxlcgMJAAACBQ50aGlzRXBvY2hNaW5lcggFAWkMb3JpZ2luQ2FsbGVyBgQHJG1hdGNoMAUOdGhpc0Vwb2NoTWluZXIDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQKZXBvY2hNaW5lcgUHJG1hdGNoMAkAAgEJAKwCAgI5bm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGV4cGVjdGVkIGZyb20gCQClCAEFCmVwb2NoTWluZXIJAAIBAkBub3QgYWxsb3dlZCB0byBmb3JnZSBibG9ja3MgaW4gdGhpcyBlcG9jaCwgZXBvY2ggbWluZXIgaXMgYWJzZW50AwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQHY2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkBDG1pbmVyQ2hhaW5JZAEIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQEDSR0MDIwOTYxMjEwMTIJAQljaGFpbk1ldGEBBQdjaGFpbklkBAtjaGFpbkhlaWdodAgFDSR0MDIwOTYxMjEwMTICXzEEC2xhc3RCbG9ja0lkCAUNJHQwMjA5NjEyMTAxMgJfMgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFC2xhc3RCbG9ja0lkAwkAAAIFDmNoZWNrUmVmZXJlbmNlBQ5jaGVja1JlZmVyZW5jZQQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzYFFGxhc3RDMkVUcmFuc2ZlckluZGV4BwMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMEDm5ld0NoYWluSGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkGBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQtsYXN0QmxvY2tJZAUHY2hhaW5JZAUXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFB2NoYWluSWQFDm5ld0NoYWluSGVpZ2h0BQxibG9ja0hhc2hIZXgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKwCAgkArAICCQClCAEJAQV2YWx1ZQEFDnRoaXNFcG9jaE1pbmVyBQNTRVAJAKQDAQUMdGhpc0Vwb2NoUmVmBQNTRVAFDGJsb2NrSGFzaEhleAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBGpvaW4BEHJld2FyZEFkZHJlc3NIZXgKAR1lbnN1cmVOb3RPdmVycmlkZU90aGVyTWluZXJQawEMZWxBZGRyZXNzSGV4BAckbWF0Y2gwCQChCAEJAQptaW5lclBrS2V5AQUMZWxBZGRyZXNzSGV4AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIFAnBrCAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICAhFFTCBtaW5lciBhZGRyZXNzIAUMZWxBZGRyZXNzSGV4AhggaXMgYWxyZWFkeSBsaW5rZWQgd2l0aCAJANgEAQUCcGsFBHVuaXQEBXBhcnRzCQC1CQIFEHJld2FyZEFkZHJlc3NIZXgCAjB4BA1yZXdhcmRBZGRyZXNzCQDdBAEJAJEDAgUFcGFydHMJAGUCCQCQAwEFBXBhcnRzAAEDCQEBIQEJAQ9pc0NvbnRyYWN0U2V0dXAACQACAQIfVGhlIGNvbnRyYWN0IGhhcyBub3QgeWV0IHNldCB1cAMJAGYCBQtNSU5fQkFMQU5DRQgJAO8HAQgFAWkMb3JpZ2luQ2FsbGVyCmdlbmVyYXRpbmcJAAIBCQCsAgIJAKwCAgkArAICAiFJbnN1ZmZpY2llbnQgZ2VuZXJhdGluZyBiYWxhbmNlOiAJAKQDAQgJAO8HAQgFAWkMb3JpZ2luQ2FsbGVyCmdlbmVyYXRpbmcCDC4gUmVxdWlyZWQ6IAkApAMBBQtNSU5fQkFMQU5DRQMJAQIhPQIJAMgBAQUNcmV3YXJkQWRkcmVzcwAUCQACAQIlcmV3YXJkQWRkcmVzcyBzaG91bGQgYmUgYW4gTDIgYWRkcmVzcwMJAGcCCQCQAwEFCWFsbE1pbmVycwAyCQACAQIPdG9vIG1hbnkgbWluZXJzCgEOY2hlY2tFeGlzdGVuY2UCBmV4aXN0cwVtaW5lcgMFBmV4aXN0cwYJAAACBQVtaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEDWFscmVhZHlFeGlzdHMKAAIkbAUJYWxsTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAcKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDmNoZWNrRXhpc3RlbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIDBQ1hbHJlYWR5RXhpc3RzBQNuaWwECG5ld01pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQWbG93ZXJjYXNlUmV3YXJkQWRkcmVzcwkA3AQBBQ1yZXdhcmRBZGRyZXNzBAVjaGVjawkBHWVuc3VyZU5vdE92ZXJyaWRlT3RoZXJNaW5lclBrAQUWbG93ZXJjYXNlUmV3YXJkQWRkcmVzcwMJAAACBQVjaGVjawUFY2hlY2sECW5ld01pbmVycwMJAAACCQCQAwEFCWFsbE1pbmVycwAABQhuZXdNaW5lcgkArAICCQCsAgIFDGFsbE1pbmVyc1N0cgUDU0VQBQhuZXdNaW5lcgQZZGVsZXRlUHJldlJld2FyZEFkZHJlc3NQawQHJG1hdGNoMAkAoggBCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAtwcmV2QWRkcmVzcwUHJG1hdGNoMAMJAAACBQtwcmV2QWRkcmVzcwkA3AQBBQ1yZXdhcmRBZGRyZXNzBQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBCm1pbmVyUGtLZXkBBQtwcmV2QWRkcmVzcwUDbmlsBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQxhbGxNaW5lcnNLZXkFCW5ld01pbmVycwkAzAgCCQELU3RyaW5nRW50cnkCCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIJAKwCAgICMHgFFmxvd2VyY2FzZVJld2FyZEFkZHJlc3MJAMwIAgkBC0JpbmFyeUVudHJ5AgkBCm1pbmVyUGtLZXkBBRZsb3dlcmNhc2VSZXdhcmRBZGRyZXNzCAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFA25pbAUZZGVsZXRlUHJldlJld2FyZEFkZHJlc3NQawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVsZWF2ZQAEDGxlYXZpbmdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIKARBza2lwTGVhdmluZ01pbmVyAgNhY2MFbWluZXIDCQAAAgUFbWluZXIFDGxlYXZpbmdNaW5lcgUDYWNjCQDNCAIFA2FjYwUFbWluZXIED3JlbWFpbmluZ01pbmVycwoAAiRsBQlhbGxNaW5lcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEHNraXBMZWF2aW5nTWluZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgQNcmV3YXJkQWRkcktleQkBFW1pbmVyUmV3YXJkQWRkcmVzc0tleQEFDGxlYXZpbmdNaW5lcgQRcHJldlJld2FyZEFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQ1yZXdhcmRBZGRyS2V5AhZtaW5lciBoYXMgbmV2ZXIgam9pbmVkAwkAAAIFEXByZXZSZXdhcmRBZGRyZXNzBRFwcmV2UmV3YXJkQWRkcmVzcwMJAAACBQ50aGlzRXBvY2hNaW5lcggFAWkMb3JpZ2luQ2FsbGVyCQACAQIcZGVzaWduYXRlZCBtaW5lciBjYW4ndCBsZWF2ZQkAzAgCCQELU3RyaW5nRW50cnkCBQxhbGxNaW5lcnNLZXkJALoJAgUPcmVtYWluaW5nTWluZXJzBQNTRVAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh0cmFuc2ZlcgEQZGVzdEVsQWRkcmVzc0hleAQMY2hlY2tBZGRyZXNzAwkAAAIJALECAQUQZGVzdEVsQWRkcmVzc0hleAUURVRIX0FERFJFU1NfU1RSX1NJWkUJAN0EAQUQZGVzdEVsQWRkcmVzc0hleAkAAgEJAKwCAgkArAICCQCsAgICFEFkZHJlc3Mgc2hvdWxkIGhhdmUgCQCkAwEFFEVUSF9BRERSRVNTX1NUUl9TSVpFAhEgY2hhcmFjdGVycywgZ290IAkApAMBCQCxAgEFEGRlc3RFbEFkZHJlc3NIZXgDCQAAAgUMY2hlY2tBZGRyZXNzBQxjaGVja0FkZHJlc3MEDGNoZWNrUGF5bWVudAMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEGCQACAQkArAICAi9FeHBlY3RlZCBvbmUgcGF5bWVudCBhcyBhIHRyYW5zZmVyIGFtb3VudCwgZ290IAkApAMBCQCQAwEIBQFpCHBheW1lbnRzAwkAAAIFDGNoZWNrUGF5bWVudAUMY2hlY2tQYXltZW50BAp0b2tlbklkU3RyCQERQGV4dHJOYXRpdmUoMTA1OCkBBQp0b2tlbklkS2V5BAd0b2tlbklkCQDZBAEFCnRva2VuSWRTdHIEAXQJAJEDAggFAWkIcGF5bWVudHMAAAQMY2hlY2tBc3NldElkBAckbWF0Y2gwCAUBdAdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEB2Fzc2V0SWQFByRtYXRjaDADCQAAAgUHYXNzZXRJZAUHdG9rZW5JZAYJAAIBCQCsAgIJAKwCAgkArAICAglFeHBlY3RlZCAFCnRva2VuSWRTdHICFSBpbiB0aGUgcGF5bWVudCwgZ290IAkA2AQBBQdhc3NldElkCQACAQkArAICCQCsAgICCUV4cGVjdGVkIAUKdG9rZW5JZFN0cgIaIGluIHRoZSBwYXltZW50LCBnb3QgV2F2ZXMDCQAAAgUMY2hlY2tBc3NldElkBQxjaGVja0Fzc2V0SWQECWxhc3RJbmRleAgJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sCXzYECXF1ZXVlU2l6ZQkAZQIFFG5hdGl2ZVRyYW5zZmVyc0NvdW50BQlsYXN0SW5kZXgED2NoZWNrUXVldWVMaW1pdAMJAGYCAKABBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdADAhD0FCXF1ZXVlU2l6ZQMJAGYCAMAMBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdACAreIEBQlxdWV1ZVNpemUDCQBmAgCAGQUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAgMLXLwUJcXVldWVTaXplAwkAZgIAgDIFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AICU69wDBQlxdWV1ZVNpemUJAAIBCQCsAgIJAKwCAgIjVHJhbnNmZXJzIGRlbmllZCBmb3IgcXVldWUgc2l6ZSBvZiAJAKQDAQUJcXVldWVTaXplAiguIFdhaXQgdW50aWwgY3VycmVudCB0cmFuc2ZlcnMgcHJvY2Vzc2VkAwkAAAIFD2NoZWNrUXVldWVMaW1pdAUPY2hlY2tRdWV1ZUxpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRduYXRpdmVUcmFuc2ZlcnNDb3VudEtleQkAZAIFFG5hdGl2ZVRyYW5zZmVyc0NvdW50AAEJAMwIAgkBFW1rTmF0aXZlVHJhbnNmZXJFbnRyeQMFFG5hdGl2ZVRyYW5zZmVyc0NvdW50BRBkZXN0RWxBZGRyZXNzSGV4CAUBdAZhbW91bnQJAMwIAgkBBEJ1cm4CBQd0b2tlbklkCAUBdAZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh3aXRoZHJhdwQMYmxvY2tIYXNoSGV4C21lcmtsZVByb29mFHRyYW5zZmVySW5kZXhJbkJsb2NrBmFtb3VudAQRd2l0aGRyYXdCbG9ja01ldGEJAQlibG9ja01ldGEBBQxibG9ja0hhc2hIZXgEE3dpdGhkcmF3QmxvY2tIZWlnaHQIBRF3aXRoZHJhd0Jsb2NrTWV0YQJfMQQUZmluYWxpemVkQmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzEEGG1haW5DaGFpbkxhc3RCbG9ja0hlaWdodAgJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sCXzEDCQBmAgUTd2l0aGRyYXdCbG9ja0hlaWdodAUUZmluYWxpemVkQmxvY2tIZWlnaHQJAAIBCQCsAgIJAKwCAgkArAICAgpFTCBibG9jayAjCQCkAwEFE3dpdGhkcmF3QmxvY2tIZWlnaHQCLSBpcyBub3QgZmluYWxpemVkLiBUaGUgY3VycmVudCBmaW5hbGl6ZWQgaXMgIwkApAMBBRRmaW5hbGl6ZWRCbG9ja0hlaWdodAMJAQIhPQIJAJADAQULbWVya2xlUHJvb2YFFFdJVEhEUkFXX1BST09GU19TSVpFCQACAQkArAICCQCsAgIJAKwCAgIJRXhwZWN0ZWQgCQCkAwEFFFdJVEhEUkFXX1BST09GU19TSVpFAg0gcHJvb2ZzLCBnb3QgCQCkAwEJAJADAQULbWVya2xlUHJvb2YDCQBmAgAABRR0cmFuc2ZlckluZGV4SW5CbG9jawkAAgEJAKwCAgIzVHJhbnNmZXIgaW5kZXggaW4gYmxvY2sgc2hvdWxkIGJlIG5vbm5lZ2F0aXZlLCBnb3QgCQCkAwEFFHRyYW5zZmVySW5kZXhJbkJsb2NrAwkAZwIAAAUGYW1vdW50CQACAQkArAICAh9BbW91bnQgc2hvdWxkIGJlIHBvc2l0aXZlLCBnb3QgCQCkAwEFBmFtb3VudAQUd2l0aGRyYXdCbG9ja0NoYWluSWQIBRF3aXRoZHJhd0Jsb2NrTWV0YQJfNAQLaXNNYWluQ2hhaW4JAAACBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAULbWFpbkNoYWluSWQEEnJlbGF0ZXNUb01haW5DaGFpbgQHJG1hdGNoMAkAnwgBCQEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAMJAAECBQckbWF0Y2gwAgNJbnQEDGZvcmtlZEhlaWdodAUHJG1hdGNoMAkAZgIFDGZvcmtlZEhlaWdodAUTd2l0aGRyYXdCbG9ja0hlaWdodAkAAgEJAKwCAgkArAICCQCsAgIFDGJsb2NrSGFzaEhleAIdIGlzIG9uIGFuIGFsdGVybmF0aXZlIGNoYWluICMJAKQDAQUUd2l0aGRyYXdCbG9ja0NoYWluSWQCOCB0aGF0IHdhcyBub3QgYXBwcm92ZWQgYnkgbWFqb3JpdHkuIFdhaXQgZm9yIHNvbWUgYmxvY2tzAwMFC2lzTWFpbkNoYWluBgUScmVsYXRlc1RvTWFpbkNoYWluBAlyZWNpcGllbnQIBQFpDG9yaWdpbkNhbGxlcgQPcmVjaXBpZW50UGtIYXNoCQDJAQIJAMoBAggFCXJlY2lwaWVudAVieXRlcwACBRRQVUJMSUNfS0VZX0hBU0hfU0laRQQPemVyb0Ftb3VudEJ5dGVzASwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQLYW1vdW50Qnl0ZXMJAJoDAQUGYW1vdW50BAtlbEV2ZW50RGF0YQkAywECCQDLAQIFD3JlY2lwaWVudFBrSGFzaAkAyQECBQ96ZXJvQW1vdW50Qnl0ZXMJAGUCCQDIAQEFD3plcm9BbW91bnRCeXRlcwkAyAEBBQthbW91bnRCeXRlcwULYW1vdW50Qnl0ZXMEEWVsRXZlbnREYXRhRGlnZXN0CQDwFQEFC2VsRXZlbnREYXRhBBJjYWxjdWxhdGVkUm9vdEhhc2gJAL0FAwULbWVya2xlUHJvb2YFEWVsRXZlbnREYXRhRGlnZXN0BRR0cmFuc2ZlckluZGV4SW5CbG9jawQQZXhwZWN0ZWRSb290SGFzaAgFEXdpdGhkcmF3QmxvY2tNZXRhAl81AwkAAAIFEmNhbGN1bGF0ZWRSb290SGFzaAUQZXhwZWN0ZWRSb290SGFzaAQHdG9rZW5JZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1OCkBBQp0b2tlbklkS2V5BAx0cmFuc2ZlcnNLZXkJARRibG9ja0UyQ1RyYW5zZmVyc0tleQEFDGJsb2NrSGFzaEhleAkAzAgCCQEHUmVpc3N1ZQMFB3Rva2VuSWQFBmFtb3VudAYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUJcmVjaXBpZW50BQZhbW91bnQFB3Rva2VuSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUMdHJhbnNmZXJzS2V5CQEJc2V0T3JGYWlsAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQx0cmFuc2ZlcnNLZXkCAAUUdHJhbnNmZXJJbmRleEluQmxvY2sFA25pbAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFEV4cGVjdGVkIHJvb3QgaGFzaDogCQDcBAEFEGV4cGVjdGVkUm9vdEhhc2gCBywgZ290OiAJANwEAQUSY2FsY3VsYXRlZFJvb3RIYXNoAhUuIEV2ZW50IGRhdGEgZGlnZXN0OiAJANoEAQURZWxFdmVudERhdGFEaWdlc3QCHy4gQ2hlY2sgeW91ciB3aXRoZHJhdyBhcmd1bWVudHMJAAIBCQCsAgIJAKwCAgIJRXhwZWN0ZWQgBQxibG9ja0hhc2hIZXgCLyB0byBiZSBlaXRoZXIgb24gdGhlIG1haW4gY2hhaW4gb3IgcmVsYXRlIHRvIGl0AWkBBXNldHVwAhNnZW5lc2lzQmxvY2tIYXNoSGV4EW1pbmVyUmV3YXJkSW5Hd2VpAwkBD2lzQ29udHJhY3RTZXR1cAAJAAIBAiRUaGUgY29udHJhY3QgaGFzIGJlZW4gYWxyZWFkeSBzZXQgdXADCQBmAgAABRFtaW5lclJld2FyZEluR3dlaQkAAgECJFRoZSBtaW5lciByZXdhcmQgbXVzdCBiZSBub25uZWdhdGl2ZQQQZ2VuZXNpc0Jsb2NrSGFzaAkA3QQBBRNnZW5lc2lzQmxvY2tIYXNoSGV4BBljaGVja0dlbmVzaXNCbG9ja0hhc2hTaXplAwkAAAIJAMgBAQUQZ2VuZXNpc0Jsb2NrSGFzaAUPQkxPQ0tfSEFTSF9TSVpFBgkAAgECGFdyb25nIGdlbmVzaXMgYmxvY2sgaGFzaAMJAAACBRljaGVja0dlbmVzaXNCbG9ja0hhc2hTaXplBRljaGVja0dlbmVzaXNCbG9ja0hhc2hTaXplBAdlbXB0eVBrASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQTZ2VuZXNpc01pbmVyQWRkcmVzcwkApwgBBQdlbXB0eVBrBBdnZW5lc2lzRXRoUmV3YXJkQWRkcmVzcwEUAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWdlbmVzaXNCbG9ja1JlZmVyZW5jZUhhc2gCQDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEBWlzc3VlCQDCCAUCBVVOSVQwAgxOYXRpdmUgdG9rZW4AAAAIBgQHdG9rZW5JZAkAuAgBBQVpc3N1ZQQQZ2VuZXNpc0Jsb2NrTWV0YQkBEG1rQmxvY2tNZXRhRW50cnkGBRNnZW5lc2lzQmxvY2tIYXNoSGV4AAAFGWdlbmVzaXNCbG9ja1JlZmVyZW5jZUhhc2gAAAkA3AQBAQAA////////////AQkAzAgCBRBnZW5lc2lzQmxvY2tNZXRhCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEAAAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMAAAAABRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5taW5lclJld2FyZEtleQURbWluZXJSZXdhcmRJbkd3ZWkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKUIAQUTZ2VuZXNpc01pbmVyQWRkcmVzcwIDLDAsBRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIFEWZpbmFsaXplZEJsb2NrS2V5BRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIFBWlzc3VlCQDMCAIJAQtTdHJpbmdFbnRyeQIFCnRva2VuSWRLZXkJANgEAQUHdG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCBRJlbEJyaWRnZUFkZHJlc3NLZXkCKjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNmE3ZQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAHbUgso=", "height": 3290416, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EkY5moE8FCU9CuGsFaX4Eaum76PqX5UM78oNkni7ezPh Next: 3RcHvbUrvhacUkEbDF6sAbEsJWivQptXXP9H9oenS514 Diff:
OldNewDifferences
686686
687687
688688 @Callable(i)
689-func join (rewardAddress) = {
689+func join (rewardAddressHex) = {
690690 func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
691691 case pk: ByteVector =>
692692 if ((pk == i.originCallerPublicKey))
696696 unit
697697 }
698698
699+ let parts = split(rewardAddressHex, "0x")
700+ let rewardAddress = fromBase16String(parts[(size(parts) - 1)])
699701 if (!(isContractSetup()))
700702 then throw("The contract has not yet set up")
701703 else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
727729 then nil
728730 else {
729731 let newMiner = toString(i.originCaller)
730- let rewardAddressHex = toBase16String(rewardAddress)
731- let check = ensureNotOverrideOtherMinerPk(rewardAddressHex)
732+ let lowercaseRewardAddress = toBase16String(rewardAddress)
733+ let check = ensureNotOverrideOtherMinerPk(lowercaseRewardAddress)
732734 if ((check == check))
733735 then {
734736 let newMiners = if ((size(allMiners) == 0))
742744 case _ =>
743745 nil
744746 }
745- ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + rewardAddressHex)), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
747+ ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + lowercaseRewardAddress)), BinaryEntry(minerPkKey(lowercaseRewardAddress), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
746748 }
747749 else throw("Strict value is not equal to itself.")
748750 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 8 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let INT_MAX = 9223372036854775807
55
66 let WAVES = 100000000
77
88 let MIN_BALANCE = (20000 * WAVES)
99
1010 let SEP = ","
1111
1212 let BLOCK_HASH_SIZE = 32
1313
1414 let PUBLIC_KEY_HASH_SIZE = 20
1515
1616 let ROOT_HASH_SIZE = 32
1717
1818 let WITHDRAW_PROOFS_SIZE = 10
1919
2020 let ETH_ADDRESS_STR_SIZE = 40
2121
2222 let MAX_CL_TO_EL_TRANSFERS = 16
2323
2424 let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
2525
2626 let allMinersKey = "allMiners"
2727
2828 let mainChainIdKey = "mainChainId"
2929
3030 let lastChainIdKey = "lastChainId"
3131
3232 let firstValidAltChainIdKey = "firstValidAltChainId"
3333
3434 let minerRewardKey = "minerReward"
3535
3636 let blockMetaK = "block_0x"
3737
3838 let finalizedBlockKey = "finalizedBlock"
3939
4040 let tokenIdKey = "tokenId"
4141
4242 let elBridgeAddressKey = "elBridgeAddress"
4343
4444 let nativeTransfersCountKey = "nativeTransfersCount"
4545
4646 func pad (i) = {
4747 let s = toString(i)
4848 match size(s) {
4949 case _ =>
5050 if ((1 == $match0))
5151 then ("0000000" + s)
5252 else if ((2 == $match0))
5353 then ("000000" + s)
5454 else if ((3 == $match0))
5555 then ("00000" + s)
5656 else if ((4 == $match0))
5757 then ("0000" + s)
5858 else if ((5 == $match0))
5959 then ("000" + s)
6060 else if ((6 == $match0))
6161 then ("00" + s)
6262 else if ((7 == $match0))
6363 then ("0" + s)
6464 else s
6565 }
6666 }
6767
6868
6969 func blockE2CTransfersKey (blockHashHex) = ("elToClTransfers_0x" + blockHashHex)
7070
7171
7272 func epochMetaKey (epoch) = ("epoch_" + pad(epoch))
7373
7474
7575 func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
7676
7777
7878 func chainMetaKey (chainId) = ("chain_" + pad(chainId))
7979
8080
8181 func chainLastHeightKey (chainId,miner) = ((("chain_" + pad(chainId)) + "_") + toString(miner))
8282
8383
8484 func chainForkedHeightKey (chainId) = (("chain_" + pad(chainId)) + "ForkedHeight")
8585
8686
8787 func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
8888
8989
9090 func minerRewardAddressKey (minerAddr) = (("miner_" + minerAddr) + "_RewardAddress")
9191
9292
9393 func minerPkKey (rewardAddress) = (("miner_0x" + rewardAddress) + "_PK")
9494
9595
9696 func minerChainIdKey (miner) = (("miner_" + toString(miner)) + "_ChainId")
9797
9898
9999 let nativeTransfersCount = valueOrElse(getInteger(this, nativeTransfersCountKey), 0)
100100
101101 func nativeTransferKey (index) = ("nativeTransfer_" + toString(index))
102102
103103
104104 func mkNativeTransferEntry (index,destElAddressHex,amount) = StringEntry(nativeTransferKey(index), ((("0x" + destElAddressHex) + SEP) + toString(amount)))
105105
106106
107107 func ensureCorrectTransfers (refTransferIndex,transferIndex,expectReward) = {
108108 let maxTransfers = if (expectReward)
109109 then (MAX_CL_TO_EL_TRANSFERS - 1)
110110 else MAX_CL_TO_EL_TRANSFERS
111111 let actualTransfers = (transferIndex - refTransferIndex)
112112 let checkNumber = if ((actualTransfers > maxTransfers))
113113 then throw(((("Allowed only " + toString(maxTransfers)) + " transfers, got ") + toString(actualTransfers)))
114114 else true
115115 if ((checkNumber == checkNumber))
116116 then if ((transferIndex >= nativeTransfersCount))
117117 then throw(((("Attempt to transfer #" + toString(transferIndex)) + ". Available transfers: ") + toString(nativeTransfersCount)))
118118 else true
119119 else throw("Strict value is not equal to itself.")
120120 }
121121
122122
123123 func amountGtEq (t,gtEq,queueSize) = if ((t.amount >= gtEq))
124124 then true
125125 else throw((((((("Transferring amount " + toString(t.amount)) + " should be >= ") + toString(gtEq)) + " for queue size of ") + toString(queueSize)) + ". Transfer more or wait"))
126126
127127
128128 func generatingBalance (address) = wavesBalance(address).generating
129129
130130
131131 func chainMeta (chainId) = {
132132 let s = getStringValue(chainMetaKey(chainId))
133133 let items = split(s, SEP)
134134 $Tuple2(parseIntValue(items[0]), items[1])
135135 }
136136
137137
138138 func mkChainMetaEntry (chainId,newChainHeight,blockHashHex) = StringEntry(chainMetaKey(chainId), ((toString(newChainHeight) + SEP) + blockHashHex))
139139
140140
141141 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
142142
143143 let $t050295095 = chainMeta(mainChainId)
144144
145145 let mainChainHeight = $t050295095._1
146146
147147 let mainChainLastBlock = $t050295095._2
148148
149149 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
150150 case s: String =>
151151 let fragments = split(s, SEP)
152152 $Tuple3(addressFromStringValue(fragments[0]), parseIntValue(fragments[1]), fragments[2])
153153 case _ =>
154154 unit
155155 }
156156
157157
158158 let $t053265450 = match epochMeta(height) {
159159 case m: (Address, Int, String) =>
160160 m
161161 case _ =>
162162 $Tuple2(unit, 0)
163163 }
164164
165165 let thisEpochMiner = $t053265450._1
166166
167167 let thisEpochRef = $t053265450._2
168168
169169 let allMinersStr = valueOrElse(getString(allMinersKey), "")
170170
171171 let allMiners = match allMinersStr {
172172 case _ =>
173173 if (("" == $match0))
174174 then nil
175175 else if ($isInstanceOf($match0, "String"))
176176 then {
177177 let raw = $match0
178178 split_4C(raw, SEP)
179179 }
180180 else throw("Match error")
181181 }
182182
183183 func blockMeta (blockId) = {
184184 let meta = getBinaryValue((blockMetaK + blockId))
185185 let metaSize = size(meta)
186186 let blockHeight = toInt(meta)
187187 let blockEpoch = toInt(meta, 8)
188188 let blockParent = take(drop(meta, 16), BLOCK_HASH_SIZE)
189189 let chainId = toInt(meta, (16 + BLOCK_HASH_SIZE))
190190 let baseOffset = (24 + BLOCK_HASH_SIZE)
191191 let remainingBytes = (metaSize - baseOffset)
192192 let e2cTransfersRootHash = if ((remainingBytes >= ROOT_HASH_SIZE))
193193 then take(drop(meta, baseOffset), ROOT_HASH_SIZE)
194194 else base58''
195195 let lastC2ETransferIndex = if (if ((remainingBytes == 8))
196196 then true
197197 else (remainingBytes > ROOT_HASH_SIZE))
198198 then toInt(meta, (baseOffset + size(e2cTransfersRootHash)))
199199 else -1
200200 $Tuple6(blockHeight, blockEpoch, blockParent, chainId, e2cTransfersRootHash, lastC2ETransferIndex)
201201 }
202202
203203
204204 func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
205205 let e2cTransfersRootHashBytes = fromBase16String(e2cTransfersRootHashHex)
206206 let rootHashBytesSize = size(e2cTransfersRootHashBytes)
207207 let checkRootHash = if (if ((rootHashBytesSize == 0))
208208 then true
209209 else (rootHashBytesSize == ROOT_HASH_SIZE))
210210 then true
211211 else throw(((("Transfers root hash should have 0 or " + toString(ROOT_HASH_SIZE)) + " bytes, got ") + toString(rootHashBytesSize)))
212212 if ((checkRootHash == checkRootHash))
213213 then {
214214 let blockMetaBytes = (((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + toBytes(chainId)) + e2cTransfersRootHashBytes) + toBytes(lastC2ETransferIndex))
215215 BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
216216 }
217217 else throw("Strict value is not equal to itself.")
218218 }
219219
220220
221221 func lastHeightBy (miner,chainId) = match getInteger(chainLastHeightKey(chainId, miner)) {
222222 case h: Int =>
223223 h
224224 case _ =>
225225 let blockHash = getStringValue(((("chain" + toString(chainId)) + "LastMinedBy") + toString(miner)))
226226 blockMeta(blockHash)._1
227227 }
228228
229229
230230 let $t074908425 = {
231231 let hitSource = match lastBlock.vrf {
232232 case vrf: ByteVector =>
233233 vrf
234234 case _ =>
235235 lastBlock.generationSignature
236236 }
237237 func processMiner (prev,miner) = {
238238 let $t077577820 = prev
239239 let prevMiner = $t077577820._1
240240 let prevTotalBalance = $t077577820._2
241241 let prevDelay = $t077577820._3
242242 let prevMiners = $t077577820._4
243243 let minerAddress = addressFromStringValue(miner)
244244 let wavesGenBalance = wavesBalance(minerAddress).generating
245245 let minerBalance = generatingBalance(minerAddress)
246246 if (if ((MIN_BALANCE > wavesGenBalance))
247247 then true
248248 else (0 >= minerBalance))
249249 then prev
250250 else {
251251 let nextDelay = calculateDelay(minerAddress, minerBalance)
252252 if ((prevDelay > nextDelay))
253253 then $Tuple4(miner, (prevTotalBalance + minerBalance), nextDelay, (prevMiners :+ miner))
254254 else $Tuple4(prevMiner, (prevTotalBalance + minerBalance), prevDelay, (prevMiners :+ miner))
255255 }
256256 }
257257
258258 let $l = allMiners
259259 let $s = size($l)
260260 let $acc0 = $Tuple4("", 0, INT_MAX, nil)
261261 func $f0_1 ($a,$i) = if (($i >= $s))
262262 then $a
263263 else processMiner($a, $l[$i])
264264
265265 func $f0_2 ($a,$i) = if (($i >= $s))
266266 then $a
267267 else throw("List size exceeds 50")
268268
269269 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
270270 }
271271
272272 let computedGenerator = $t074908425._1
273273
274274 let computedTotalBalance = $t074908425._2
275275
276276 let $t084278493 = blockMeta(mainChainLastBlock)
277277
278278 let mclbIgnored1 = $t084278493._1
279279
280280 let mainChainEpoch = $t084278493._2
281281
282282 func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
283283 let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
284284 let halfBalance = (computedTotalBalance / 2)
285285 func step (prev,next) = {
286286 let $t088598923 = prev
287287 let thisEpoch = $t088598923._1
288288 let maybeSafeEpoch = $t088598923._2
289289 let totalBalance = $t088598923._3
290290 let prevMiners = $t088598923._4
291291 match maybeSafeEpoch {
292292 case _: Unit =>
293293 let $t089819147 = if ((thisEpoch == height))
294294 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
295295 else value(epochMeta(thisEpoch))
296296 let miner = $t089819147._1
297297 let prevEpoch = $t089819147._2
298298 let lastBlockHash = $t089819147._3
299299 if (if ((prevEpoch == 0))
300300 then true
301301 else ((height - thisEpoch) >= 100))
302302 then $Tuple4(thisEpoch, lastBlockHash, totalBalance, allMiners)
303303 else {
304304 let $t093019503 = if (containsElement(prevMiners, miner))
305305 then $Tuple2(totalBalance, prevMiners)
306306 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
307307 let newTotalBalance = $t093019503._1
308308 let newMiners = $t093019503._2
309309 if ((newTotalBalance > halfBalance))
310310 then $Tuple4(thisEpoch, lastBlockHash, newTotalBalance, allMiners)
311311 else $Tuple4(prevEpoch, unit, newTotalBalance, newMiners)
312312 }
313313 case _ =>
314314 prev
315315 }
316316 }
317317
318318 let $t097369832 = {
319319 let $l = offsets_100
320320 let $s = size($l)
321321 let $acc0 = $Tuple4(height, unit, 0, nil)
322322 func $f0_1 ($a,$i) = if (($i >= $s))
323323 then $a
324324 else step($a, $l[$i])
325325
326326 func $f0_2 ($a,$i) = if (($i >= $s))
327327 then $a
328328 else throw("List size exceeds 100")
329329
330330 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
331331 }
332332 let fallbackEpoch = $t097369832._1
333333 let finalizedBlockHashOpt = $t097369832._2
334334 match finalizedBlockHashOpt {
335335 case finalizedBlockHash: String =>
336336 finalizedBlockHash
337337 case _ =>
338338 value(epochMeta(fallbackEpoch))._3
339339 }
340340 }
341341
342342
343343 func supportingBalance (chainId) = {
344344 func addBalance (acc,generatorStr) = {
345345 let $t01010210138 = acc
346346 let totalBalance = $t01010210138._1
347347 let generators = $t01010210138._2
348348 let generator = addressFromStringValue(generatorStr)
349349 if (containsElement(generators, generator))
350350 then acc
351351 else {
352352 let balance = generatingBalance(generator)
353353 $Tuple2((totalBalance + balance), (generators :+ generator))
354354 }
355355 }
356356
357357 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
358358 let $t01046010525 = {
359359 let $l = allGenerators
360360 let $s = size($l)
361361 let $acc0 = $Tuple2(0, nil)
362362 func $f0_1 ($a,$i) = if (($i >= $s))
363363 then $a
364364 else addBalance($a, $l[$i])
365365
366366 func $f0_2 ($a,$i) = if (($i >= $s))
367367 then $a
368368 else throw("List size exceeds 100")
369369
370370 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
371371 }
372372 let balance = $t01046010525._1
373373 let _g = $t01046010525._2
374374 balance
375375 }
376376
377377
378378 func isContractSetup () = isDefined(getInteger(minerRewardKey))
379379
380380
381381 func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
382382 then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
383383 else unit
384384
385385
386386 func isReferenceCorrect (reference,lastBlock) = if ((reference == lastBlock))
387387 then unit
388388 else throw(((("Expected a reference to the chain last block: 0x" + lastBlock) + ". Got: 0x") + reference))
389389
390390
391391 func chainIsInactive (chainId) = {
392392 let firstBlockId = getStringValue(chainFirstBlockIdKey(chainId))
393393 let firstValidAltChainId = valueOrElse(getInteger(firstValidAltChainIdKey), 0)
394394 if ((firstValidAltChainId > chainId))
395395 then true
396396 else (blockMeta(getStringValue(finalizedBlockKey))._1 > blockMeta(firstBlockId)._1)
397397 }
398398
399399
400400 func minerChainId (miner) = valueOrElse(getInteger(minerChainIdKey(miner)), getInteger(("chainIdOf" + toString(miner))))
401401
402402
403403 func ensureExpectedOrInactiveChain (generator,expectedChainId,checkHeightBlock) = {
404404 let heightIsCorrect = match checkHeightBlock {
405405 case blockHash: String =>
406406 let lastMinedBlockHeight = lastHeightBy(generator, mainChainId)
407407 ((blockMeta(blockHash)._1 + 1) > lastMinedBlockHeight)
408408 case _ =>
409409 true
410410 }
411411 match minerChainId(generator) {
412412 case currentId: Int =>
413413 if (if ((currentId == expectedChainId))
414414 then true
415415 else if (chainIsInactive(currentId))
416416 then heightIsCorrect
417417 else false)
418418 then unit
419419 else throw(("miner is mining other chain " + toString(currentId)))
420420 case _ =>
421421 unit
422422 }
423423 }
424424
425425
426426 let heightString = (" at height " + toString(height))
427427
428428 func vrfAt (height) = valueOrErrorMessage(valueOrErrorMessage(blockInfoByHeight(height), ("last block is not available" + heightString)).vrf, ("VRF is not available" + heightString))
429429
430430
431431 func ensureCorrectEpoch (expectedVRF) = {
432432 let actualVRF = vrfAt(height)
433433 if ((expectedVRF == actualVRF))
434434 then unit
435435 else throw((((("Expected VRF " + toBase58String(expectedVRF)) + " does not match actual ") + toBase58String(actualVRF)) + heightString))
436436 }
437437
438438
439439 func addSupporter (chainId,generator) = {
440440 let supportersStr = getStringValue(supportersKey(chainId))
441441 let supporters = split_4C(supportersStr, SEP)
442442 if (containsElement(supporters, toString(generator)))
443443 then nil
444444 else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
445445 }
446446
447447
448448 func setOrFail (flags,index) = if ((0 > index))
449449 then throw(("Can't withdraw at negative index: " + toString(index)))
450450 else {
451451 let flagsSize = size(flags)
452452 if ((index >= flagsSize))
453453 then {
454454 let addZeroes = (index - flagsSize)
455455 if ((addZeroes > size(zeroesStr)))
456456 then throw((("Can't add " + toString(addZeroes)) + " empty flags. Contact with developers"))
457457 else ((flags + take(zeroesStr, addZeroes)) + "1")
458458 }
459459 else {
460460 let tail = drop(flags, index)
461461 let atIndex = take(tail, 1)
462462 if ((atIndex == "0"))
463463 then ((take(flags, index) + "1") + drop(tail, 1))
464464 else throw((("Transfer #" + toString(index)) + " has been already taken"))
465465 }
466466 }
467467
468468
469469 func validateBlockHash (hexStr) = {
470470 let decodedBytes = fromBase16String(hexStr)
471471 if ((size(decodedBytes) != BLOCK_HASH_SIZE))
472472 then throw("invalid block id length")
473473 else hexStr
474474 }
475475
476476
477477 func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
478478 let curFinalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
479479 let newFinalizedBlockHash = calculateFinalizedBlockHash(caller, prevEpoch, newBlockHashHex)
480480 if (if ((newFinalizedBlockHash == newBlockHashHex))
481481 then true
482482 else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockHeight))
483483 then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
484484 else nil
485485 }
486486
487487
488488 @Callable(i)
489489 func extendMainChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
490490 let checkBlockHash = validateBlockHash(blockHashHex)
491491 if ((checkBlockHash == checkBlockHash))
492492 then {
493493 let checkEpoch = ensureCorrectEpoch(vrf)
494494 if ((checkEpoch == checkEpoch))
495495 then {
496496 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, unit)
497497 if ((checkChain == checkChain))
498498 then {
499499 let checkReference = isReferenceCorrect(referenceHex, mainChainLastBlock)
500500 if ((checkReference == checkReference))
501501 then {
502502 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
503503 if ((checkTransfers == checkTransfers))
504504 then {
505505 let thisEpochMeta = match epochMeta(height) {
506506 case _: Unit =>
507507 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(mainChainEpoch)) + SEP) + blockHashHex))
508508 case other =>
509509 throw("Epoch already started")
510510 }
511511 if ((thisEpochMeta == thisEpochMeta))
512512 then {
513513 let checkGenerator = ensureMiningEpoch(i.originCaller)
514514 if ((checkGenerator == checkGenerator))
515515 then {
516516 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, mainChainEpoch)
517517 let newChainHeight = (mainChainHeight + 1)
518518 ([mkBlockMetaEntry(blockHashHex, newChainHeight, mainChainLastBlock, mainChainId, e2cTransfersRootHashHex, lastC2ETransferIndex), mkChainMetaEntry(mainChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), mainChainId), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), thisEpochMeta] ++ updateFinalizedBlock)
519519 }
520520 else throw("Strict value is not equal to itself.")
521521 }
522522 else throw("Strict value is not equal to itself.")
523523 }
524524 else throw("Strict value is not equal to itself.")
525525 }
526526 else throw("Strict value is not equal to itself.")
527527 }
528528 else throw("Strict value is not equal to itself.")
529529 }
530530 else throw("Strict value is not equal to itself.")
531531 }
532532 else throw("Strict value is not equal to itself.")
533533 }
534534
535535
536536
537537 @Callable(i)
538538 func startAltChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
539539 let checkBlockHash = validateBlockHash(blockHashHex)
540540 if ((checkBlockHash == checkBlockHash))
541541 then {
542542 let checkEpoch = ensureCorrectEpoch(vrf)
543543 if ((checkEpoch == checkEpoch))
544544 then {
545545 let $t01613216245 = blockMeta(referenceHex)
546546 let refChainHeight = $t01613216245._1
547547 let refEpoch = $t01613216245._2
548548 let refIgnored1 = $t01613216245._3
549549 let refIgnored2 = $t01613216245._4
550550 let refIgnored3 = $t01613216245._5
551551 let refTransferIndex = $t01613216245._6
552552 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
553553 let epochRef = if ((refEpoch >= finalizedEpoch))
554554 then refEpoch
555555 else throw((((("Can not start alt chain from epoch " + toString(refEpoch)) + ", epoch ") + toString(finalizedEpoch)) + " is finalized"))
556556 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, referenceHex)
557557 if ((checkChain == checkChain))
558558 then {
559559 let checkTransfers = ensureCorrectTransfers(refTransferIndex, lastC2ETransferIndex, true)
560560 if ((checkTransfers == checkTransfers))
561561 then {
562562 let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
563563 let newChainHeight = (refChainHeight + 1)
564564 let thisEpochMeta = match epochMeta(height) {
565565 case _: Unit =>
566566 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(epochRef)) + SEP) + blockHashHex))
567567 case other =>
568568 throw("Epoch already started")
569569 }
570570 let checkGenerator = ensureMiningEpoch(i.originCaller)
571571 if ((checkGenerator == checkGenerator))
572572 then [thisEpochMeta, mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, newChainId, e2cTransfersRootHashHex, lastC2ETransferIndex), StringEntry(chainFirstBlockIdKey(newChainId), blockHashHex), mkChainMetaEntry(newChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), newChainId), IntegerEntry(chainLastHeightKey(newChainId, i.originCaller), newChainHeight), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastChainIdKey, newChainId)]
573573 else throw("Strict value is not equal to itself.")
574574 }
575575 else throw("Strict value is not equal to itself.")
576576 }
577577 else throw("Strict value is not equal to itself.")
578578 }
579579 else throw("Strict value is not equal to itself.")
580580 }
581581 else throw("Strict value is not equal to itself.")
582582 }
583583
584584
585585
586586 @Callable(i)
587587 func extendAltChain (blockHashHex,referenceHex,vrf,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
588588 let checkBlockHash = validateBlockHash(blockHashHex)
589589 if ((checkBlockHash == checkBlockHash))
590590 then {
591591 let checkEpoch = ensureCorrectEpoch(vrf)
592592 if ((checkEpoch == checkEpoch))
593593 then {
594594 let chainFirstBlockMeta = blockMeta(getStringValue(chainFirstBlockIdKey(chainId)))
595595 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
596596 if ((checkChain == checkChain))
597597 then {
598598 let $t01855818612 = chainMeta(chainId)
599599 let chainHeight = $t01855818612._1
600600 let chainLastBlock = $t01855818612._2
601601 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
602602 if ((checkReference == checkReference))
603603 then {
604604 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
605605 if ((checkTransfers == checkTransfers))
606606 then {
607607 let newChainHeight = (chainHeight + 1)
608608 let prevEpoch = blockMeta(referenceHex)._2
609609 let updateMainChainData = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
610610 then {
611611 let lastChainId = valueOrElse(getInteger(lastChainIdKey), 0)
612612 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, prevEpoch)
613613 ([IntegerEntry(chainForkedHeightKey(mainChainId), chainFirstBlockMeta._1), IntegerEntry(mainChainIdKey, chainId), IntegerEntry(firstValidAltChainIdKey, (lastChainId + 1))] ++ updateFinalizedBlock)
614614 }
615615 else nil
616616 let thisEpochMeta = match epochMeta(height) {
617617 case _: Unit =>
618618 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(prevEpoch)) + SEP) + blockHashHex))
619619 case other =>
620620 throw("Epoch already started")
621621 }
622622 if ((thisEpochMeta == thisEpochMeta))
623623 then {
624624 let checkGenerator = ensureMiningEpoch(i.originCaller)
625625 if ((checkGenerator == checkGenerator))
626626 then {
627627 let updateMainChainLastMinedBlock = if (if ((updateMainChainData == nil))
628628 then (valueOrElse(minerChainId(i.originCaller), 0) != chainId)
629629 else false)
630630 then [IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), chainFirstBlockMeta._1)]
631631 else nil
632632 ((([mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, chainId, e2cTransfersRootHashHex, lastC2ETransferIndex), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), thisEpochMeta, IntegerEntry(minerChainIdKey(i.originCaller), chainId), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight)] ++ updateMainChainData) ++ addSupporter(chainId, i.originCaller)) ++ updateMainChainLastMinedBlock)
633633 }
634634 else throw("Strict value is not equal to itself.")
635635 }
636636 else throw("Strict value is not equal to itself.")
637637 }
638638 else throw("Strict value is not equal to itself.")
639639 }
640640 else throw("Strict value is not equal to itself.")
641641 }
642642 else throw("Strict value is not equal to itself.")
643643 }
644644 else throw("Strict value is not equal to itself.")
645645 }
646646 else throw("Strict value is not equal to itself.")
647647 }
648648
649649
650650
651651 @Callable(i)
652652 func appendBlock (blockHashHex,referenceHex,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
653653 let checkCaller = if ((thisEpochMiner == i.originCaller))
654654 then true
655655 else match thisEpochMiner {
656656 case epochMiner: Address =>
657657 throw(("not allowed to forge blocks in this epoch, expected from " + toString(epochMiner)))
658658 case _ =>
659659 throw("not allowed to forge blocks in this epoch, epoch miner is absent")
660660 }
661661 if ((checkCaller == checkCaller))
662662 then {
663663 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
664664 let $t02096121012 = chainMeta(chainId)
665665 let chainHeight = $t02096121012._1
666666 let lastBlockId = $t02096121012._2
667667 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
668668 if ((checkReference == checkReference))
669669 then {
670670 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, false)
671671 if ((checkTransfers == checkTransfers))
672672 then {
673673 let newChainHeight = (chainHeight + 1)
674674 let checkBlockHash = validateBlockHash(blockHashHex)
675675 if ((checkBlockHash == checkBlockHash))
676676 then [mkBlockMetaEntry(blockHashHex, newChainHeight, lastBlockId, chainId, e2cTransfersRootHashHex, lastC2ETransferIndex), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), StringEntry(epochMetaKey(height), ((((toString(value(thisEpochMiner)) + SEP) + toString(thisEpochRef)) + SEP) + blockHashHex))]
677677 else throw("Strict value is not equal to itself.")
678678 }
679679 else throw("Strict value is not equal to itself.")
680680 }
681681 else throw("Strict value is not equal to itself.")
682682 }
683683 else throw("Strict value is not equal to itself.")
684684 }
685685
686686
687687
688688 @Callable(i)
689-func join (rewardAddress) = {
689+func join (rewardAddressHex) = {
690690 func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
691691 case pk: ByteVector =>
692692 if ((pk == i.originCallerPublicKey))
693693 then unit
694694 else throw(((("EL miner address " + elAddressHex) + " is already linked with ") + toBase58String(pk)))
695695 case _ =>
696696 unit
697697 }
698698
699+ let parts = split(rewardAddressHex, "0x")
700+ let rewardAddress = fromBase16String(parts[(size(parts) - 1)])
699701 if (!(isContractSetup()))
700702 then throw("The contract has not yet set up")
701703 else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
702704 then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
703705 else if ((size(rewardAddress) != 20))
704706 then throw("rewardAddress should be an L2 address")
705707 else if ((size(allMiners) >= 50))
706708 then throw("too many miners")
707709 else {
708710 func checkExistence (exists,miner) = if (exists)
709711 then true
710712 else (miner == toString(i.originCaller))
711713
712714 let alreadyExists = {
713715 let $l = allMiners
714716 let $s = size($l)
715717 let $acc0 = false
716718 func $f0_1 ($a,$i) = if (($i >= $s))
717719 then $a
718720 else checkExistence($a, $l[$i])
719721
720722 func $f0_2 ($a,$i) = if (($i >= $s))
721723 then $a
722724 else throw("List size exceeds 50")
723725
724726 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
725727 }
726728 if (alreadyExists)
727729 then nil
728730 else {
729731 let newMiner = toString(i.originCaller)
730- let rewardAddressHex = toBase16String(rewardAddress)
731- let check = ensureNotOverrideOtherMinerPk(rewardAddressHex)
732+ let lowercaseRewardAddress = toBase16String(rewardAddress)
733+ let check = ensureNotOverrideOtherMinerPk(lowercaseRewardAddress)
732734 if ((check == check))
733735 then {
734736 let newMiners = if ((size(allMiners) == 0))
735737 then newMiner
736738 else ((allMinersStr + SEP) + newMiner)
737739 let deletePrevRewardAddressPk = match getString(minerRewardAddressKey(newMiner)) {
738740 case prevAddress: String =>
739741 if ((prevAddress == toBase16String(rewardAddress)))
740742 then nil
741743 else [DeleteEntry(minerPkKey(prevAddress))]
742744 case _ =>
743745 nil
744746 }
745- ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + rewardAddressHex)), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
747+ ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + lowercaseRewardAddress)), BinaryEntry(minerPkKey(lowercaseRewardAddress), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
746748 }
747749 else throw("Strict value is not equal to itself.")
748750 }
749751 }
750752 }
751753
752754
753755
754756 @Callable(i)
755757 func leave () = {
756758 let leavingMiner = toString(i.originCaller)
757759 func skipLeavingMiner (acc,miner) = if ((miner == leavingMiner))
758760 then acc
759761 else (acc :+ miner)
760762
761763 let remainingMiners = {
762764 let $l = allMiners
763765 let $s = size($l)
764766 let $acc0 = nil
765767 func $f0_1 ($a,$i) = if (($i >= $s))
766768 then $a
767769 else skipLeavingMiner($a, $l[$i])
768770
769771 func $f0_2 ($a,$i) = if (($i >= $s))
770772 then $a
771773 else throw("List size exceeds 50")
772774
773775 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
774776 }
775777 let rewardAddrKey = minerRewardAddressKey(leavingMiner)
776778 let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
777779 if ((prevRewardAddress == prevRewardAddress))
778780 then if ((thisEpochMiner == i.originCaller))
779781 then throw("designated miner can't leave")
780782 else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
781783 else throw("Strict value is not equal to itself.")
782784 }
783785
784786
785787
786788 @Callable(i)
787789 func transfer (destElAddressHex) = {
788790 let checkAddress = if ((size(destElAddressHex) == ETH_ADDRESS_STR_SIZE))
789791 then fromBase16String(destElAddressHex)
790792 else throw(((("Address should have " + toString(ETH_ADDRESS_STR_SIZE)) + " characters, got ") + toString(size(destElAddressHex))))
791793 if ((checkAddress == checkAddress))
792794 then {
793795 let checkPayment = if ((size(i.payments) == 1))
794796 then true
795797 else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
796798 if ((checkPayment == checkPayment))
797799 then {
798800 let tokenIdStr = getStringValue(tokenIdKey)
799801 let tokenId = fromBase58String(tokenIdStr)
800802 let t = i.payments[0]
801803 let checkAssetId = match t.assetId {
802804 case assetId: ByteVector =>
803805 if ((assetId == tokenId))
804806 then true
805807 else throw(((("Expected " + tokenIdStr) + " in the payment, got ") + toBase58String(assetId)))
806808 case _ =>
807809 throw((("Expected " + tokenIdStr) + " in the payment, got Waves"))
808810 }
809811 if ((checkAssetId == checkAssetId))
810812 then {
811813 let lastIndex = blockMeta(mainChainLastBlock)._6
812814 let queueSize = (nativeTransfersCount - lastIndex)
813815 let checkQueueLimit = if ((160 > queueSize))
814816 then amountGtEq(t, 1000000, queueSize)
815817 else if ((1600 > queueSize))
816818 then amountGtEq(t, 10000000, queueSize)
817819 else if ((3200 > queueSize))
818820 then amountGtEq(t, 100000000, queueSize)
819821 else if ((6400 > queueSize))
820822 then amountGtEq(t, 1000000000, queueSize)
821823 else throw((("Transfers denied for queue size of " + toString(queueSize)) + ". Wait until current transfers processed"))
822824 if ((checkQueueLimit == checkQueueLimit))
823825 then [IntegerEntry(nativeTransfersCountKey, (nativeTransfersCount + 1)), mkNativeTransferEntry(nativeTransfersCount, destElAddressHex, t.amount), Burn(tokenId, t.amount)]
824826 else throw("Strict value is not equal to itself.")
825827 }
826828 else throw("Strict value is not equal to itself.")
827829 }
828830 else throw("Strict value is not equal to itself.")
829831 }
830832 else throw("Strict value is not equal to itself.")
831833 }
832834
833835
834836
835837 @Callable(i)
836838 func withdraw (blockHashHex,merkleProof,transferIndexInBlock,amount) = {
837839 let withdrawBlockMeta = blockMeta(blockHashHex)
838840 let withdrawBlockHeight = withdrawBlockMeta._1
839841 let finalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
840842 let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
841843 if ((withdrawBlockHeight > finalizedBlockHeight))
842844 then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
843845 else if ((size(merkleProof) != WITHDRAW_PROOFS_SIZE))
844846 then throw(((("Expected " + toString(WITHDRAW_PROOFS_SIZE)) + " proofs, got ") + toString(size(merkleProof))))
845847 else if ((0 > transferIndexInBlock))
846848 then throw(("Transfer index in block should be nonnegative, got " + toString(transferIndexInBlock)))
847849 else if ((0 >= amount))
848850 then throw(("Amount should be positive, got " + toString(amount)))
849851 else {
850852 let withdrawBlockChainId = withdrawBlockMeta._4
851853 let isMainChain = (withdrawBlockChainId == mainChainId)
852854 let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
853855 case forkedHeight: Int =>
854856 (forkedHeight > withdrawBlockHeight)
855857 case _ =>
856858 throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
857859 }
858860 if (if (isMainChain)
859861 then true
860862 else relatesToMainChain)
861863 then {
862864 let recipient = i.originCaller
863865 let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
864866 let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
865867 let amountBytes = toBytes(amount)
866868 let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
867869 let elEventDataDigest = blake2b256_16Kb(elEventData)
868870 let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
869871 let expectedRootHash = withdrawBlockMeta._5
870872 if ((calculatedRootHash == expectedRootHash))
871873 then {
872874 let tokenId = fromBase58String(getStringValue(tokenIdKey))
873875 let transfersKey = blockE2CTransfersKey(blockHashHex)
874876 [Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
875877 }
876878 else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
877879 }
878880 else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
879881 }
880882 }
881883
882884
883885
884886 @Callable(i)
885887 func setup (genesisBlockHashHex,minerRewardInGwei) = if (isContractSetup())
886888 then throw("The contract has been already set up")
887889 else if ((0 > minerRewardInGwei))
888890 then throw("The miner reward must be nonnegative")
889891 else {
890892 let genesisBlockHash = fromBase16String(genesisBlockHashHex)
891893 let checkGenesisBlockHashSize = if ((size(genesisBlockHash) == BLOCK_HASH_SIZE))
892894 then true
893895 else throw("Wrong genesis block hash")
894896 if ((checkGenesisBlockHashSize == checkGenesisBlockHashSize))
895897 then {
896898 let emptyPk = base58'11111111111111111111111111111111'
897899 let genesisMinerAddress = addressFromPublicKey(emptyPk)
898900 let genesisEthRewardAddress = base58'11111111111111111111'
899901 let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
900902 let issue = Issue("UNIT0", "Native token", 0, 8, true)
901903 let tokenId = calculateAssetId(issue)
902904 let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, 0, toBase16String(base58''), -1)
903905 [genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, "0x0000000000000000000000000000000000006a7e")]
904906 }
905907 else throw("Strict value is not equal to itself.")
906908 }
907909
908910

github/deemru/w8io/026f985 
93.72 ms