tx · BQBbkSKsGaXUizoNRKY4fRvWjfiSvYxu7VfN1gVNdowc

3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch:  -0.04300000 Waves

2024.08.30 13:29 [3261511] smart account 3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch > SELF 0.00000000 Waves

{ "type": 13, "id": "BQBbkSKsGaXUizoNRKY4fRvWjfiSvYxu7VfN1gVNdowc", "fee": 4300000, "feeAssetId": null, "timestamp": 1725013848832, "version": 2, "chainId": 84, "sender": "3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch", "senderPublicKey": "3xjN6fjYDXBGUE1mcRw2Fvr4R6tEZnuJA98QFGF99sXd", "proofs": [ "4VLKnvG9NbAYV3H6H2313kuCJ1wd5f8uLYCsf9iiYKaJBT7rmG1a9BXELirvua7jR9pyhwH3rkcw9L5jFxF1toYK" ], "script": "base64:CAJCCAISBgoECAgIARIHCgUICAEIARIHCgUICAEIARIICgYBCAgBCAESAwoBAhIAEgMKAQgSBgoECBIBARIGCgQIAQgIUgAHSU5UX01BWAD//////////38ABVdBVkVTAIDC1y8AC01JTl9CQUxBTkNFCQBoAgCgnAEFBVdBVkVTAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgAAxBRERSRVNTX1NJWkUAGgAUUFVCTElDX0tFWV9IQVNIX1NJWkUAFAAOUk9PVF9IQVNIX1NJWkUAIAAUV0lUSERSQVdfUFJPT0ZTX1NJWkUACgAURVRIX0FERFJFU1NfU1RSX1NJWkUAKAAWTUFYX0NMX1RPX0VMX1RSQU5TRkVSUwAQAAl6ZXJvZXNTdHICgAgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwABB0aGlzRXBvY2hEYXRhS2V5Ag10aGlzRXBvY2hEYXRhAAxhbGxNaW5lcnNLZXkCCWFsbE1pbmVycwAObWFpbkNoYWluSWRLZXkCC21haW5DaGFpbklkAA5sYXN0Q2hhaW5JZEtleQILbGFzdENoYWluSWQAF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AhRmaXJzdFZhbGlkQWx0Q2hhaW5JZAAObWluZXJSZXdhcmRLZXkCC21pbmVyUmV3YXJkABlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5AhZzdGFraW5nQ29udHJhY3RBZGRyZXNzAApibG9ja01ldGFLAghibG9ja18weAARZmluYWxpemVkQmxvY2tLZXkCDmZpbmFsaXplZEJsb2NrAAp0b2tlbklkS2V5Agd0b2tlbklkABJlbEJyaWRnZUFkZHJlc3NLZXkCD2VsQnJpZGdlQWRkcmVzcwAXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkCFG5hdGl2ZVRyYW5zZmVyc0NvdW50AQNwYWQBAWkEAXMJAKQDAQUBaQQHJG1hdGNoMAkAsQIBBQFzAwkAAAIAAQUHJG1hdGNoMAkArAICAgcwMDAwMDAwBQFzAwkAAAIAAgUHJG1hdGNoMAkArAICAgYwMDAwMDAFAXMDCQAAAgADBQckbWF0Y2gwCQCsAgICBTAwMDAwBQFzAwkAAAIABAUHJG1hdGNoMAkArAICAgQwMDAwBQFzAwkAAAIABQUHJG1hdGNoMAkArAICAgMwMDAFAXMDCQAAAgAGBQckbWF0Y2gwCQCsAgICAjAwBQFzAwkAAAIABwUHJG1hdGNoMAkArAICAgEwBQFzBQFzARdibG9ja0VsVG9DbFRyYW5zZmVyc0tleQEMYmxvY2tIYXNoSGV4CQCsAgICEmVsVG9DbFRyYW5zZmVyc18weAUMYmxvY2tIYXNoSGV4AQxlcG9jaE1ldGFLZXkBBWVwb2NoCQCsAgICBmVwb2NoXwkBA3BhZAEFBWVwb2NoARRjaGFpbkZpcnN0QmxvY2tJZEtleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCCkZpcnN0QmxvY2sBDGNoYWluTWV0YUtleQEHY2hhaW5JZAkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkARJjaGFpbkxhc3RIZWlnaHRLZXkCB2NoYWluSWQFbWluZXIJAKwCAgkArAICCQCsAgICBmNoYWluXwkBA3BhZAEFB2NoYWluSWQCAV8JAKUIAQUFbWluZXIBFGNoYWluRm9ya2VkSGVpZ2h0S2V5AQdjaGFpbklkCQCsAgIJAKwCAgIGY2hhaW5fCQEDcGFkAQUHY2hhaW5JZAIMRm9ya2VkSGVpZ2h0AQ1zdXBwb3J0ZXJzS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKU3VwcG9ydGVycwEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQltaW5lckFkZHIJAKwCAgkArAICAgZtaW5lcl8FCW1pbmVyQWRkcgIOX1Jld2FyZEFkZHJlc3MBCm1pbmVyUGtLZXkBDXJld2FyZEFkZHJlc3MJAKwCAgkArAICAghtaW5lcl8weAUNcmV3YXJkQWRkcmVzcwIDX1BLAQ9taW5lckNoYWluSWRLZXkBBW1pbmVyCQCsAgIJAKwCAgIGbWluZXJfCQClCAEFBW1pbmVyAghfQ2hhaW5JZAAUbmF0aXZlVHJhbnNmZXJzQ291bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkAAAERbmF0aXZlVHJhbnNmZXJLZXkBBWluZGV4CQCsAgICD25hdGl2ZVRyYW5zZmVyXwkApAMBBQVpbmRleAEVbWtOYXRpdmVUcmFuc2ZlckVudHJ5AwVpbmRleBBkZXN0RWxBZGRyZXNzSGV4BmFtb3VudAkBC1N0cmluZ0VudHJ5AgkBEW5hdGl2ZVRyYW5zZmVyS2V5AQUFaW5kZXgJAKwCAgkArAICCQCsAgICAjB4BRBkZXN0RWxBZGRyZXNzSGV4BQNTRVAJAKQDAQUGYW1vdW50ARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAxByZWZUcmFuc2ZlckluZGV4DXRyYW5zZmVySW5kZXgMZXhwZWN0UmV3YXJkBAxtYXhUcmFuc2ZlcnMDBQxleHBlY3RSZXdhcmQJAGUCBRZNQVhfQ0xfVE9fRUxfVFJBTlNGRVJTAAEFFk1BWF9DTF9UT19FTF9UUkFOU0ZFUlMED2FjdHVhbFRyYW5zZmVycwkAZQIFDXRyYW5zZmVySW5kZXgFEHJlZlRyYW5zZmVySW5kZXgEC2NoZWNrTnVtYmVyAwkAZgIFD2FjdHVhbFRyYW5zZmVycwUMbWF4VHJhbnNmZXJzCQACAQkArAICCQCsAgIJAKwCAgINQWxsb3dlZCBvbmx5IAkApAMBBQxtYXhUcmFuc2ZlcnMCECB0cmFuc2ZlcnMsIGdvdCAJAKQDAQUPYWN0dWFsVHJhbnNmZXJzBgMJAAACBQtjaGVja051bWJlcgULY2hlY2tOdW1iZXIDCQBnAgUNdHJhbnNmZXJJbmRleAUUbmF0aXZlVHJhbnNmZXJzQ291bnQJAAIBCQCsAgIJAKwCAgkArAICAhVBdHRlbXB0IHRvIHRyYW5zZmVyICMJAKQDAQUNdHJhbnNmZXJJbmRleAIXLiBBdmFpbGFibGUgdHJhbnNmZXJzOiAJAKQDAQUUbmF0aXZlVHJhbnNmZXJzQ291bnQGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQphbW91bnRHdEVxAwF0BGd0RXEJcXVldWVTaXplAwkAZwIIBQF0BmFtb3VudAUEZ3RFcQYJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhRUcmFuc2ZlcnJpbmcgYW1vdW50IAkApAMBCAUBdAZhbW91bnQCDiBzaG91bGQgYmUgPj0gCQCkAwEFBGd0RXECEyBmb3IgcXVldWUgc2l6ZSBvZiAJAKQDAQUJcXVldWVTaXplAhcuIFRyYW5zZmVyIG1vcmUgb3Igd2FpdAAWc3Rha2luZ0NvbnRyYWN0QWRkcmVzcwQHJG1hdGNoMAkAnQgCBQR0aGlzBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAXMJAKwCAgIiaW52YWxpZCBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3M6IAUBcwkBB0FkZHJlc3MBCQERQGV4dHJOYXRpdmUoMTA1MikCBQR0aGlzBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5ARFnZW5lcmF0aW5nQmFsYW5jZQEHYWRkcmVzcwQHJG1hdGNoMAkAnQgCBRZzdGFraW5nQ29udHJhY3RBZGRyZXNzCQCsAgICBCVzX18JAKUIAQUHYWRkcmVzcwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3N0cgUHJG1hdGNoMAQJcGFyYW1MaXN0CQC1CQIFA3N0cgICX18ECnByZXZIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAQQLcHJldkJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAgQKbmV4dEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAADBAtuZXh0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAAEAwkAZwIFBmhlaWdodAUKbmV4dEhlaWdodAULbmV4dEJhbGFuY2UDCQBnAgUGaGVpZ2h0BQpwcmV2SGVpZ2h0BQtwcmV2QmFsYW5jZQAAAAABCWNoYWluTWV0YQEHY2hhaW5JZAQBcwkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDGNoYWluTWV0YUtleQEFB2NoYWluSWQEBWl0ZW1zCQC1CQIFAXMFA1NFUAkAlAoCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFaXRlbXMAAAkAkQMCBQVpdGVtcwABARBta0NoYWluTWV0YUVudHJ5AwdjaGFpbklkDm5ld0NoYWluSGVpZ2h0DGJsb2NrSGFzaEhleAkBC1N0cmluZ0VudHJ5AgkBDGNoYWluTWV0YUtleQEFB2NoYWluSWQJAKwCAgkArAICCQCkAwEFDm5ld0NoYWluSGVpZ2h0BQNTRVAFDGJsb2NrSGFzaEhleAALbWFpbkNoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObWFpbkNoYWluSWRLZXkAAAALJHQwNTg4MTU5NDcJAQljaGFpbk1ldGEBBQttYWluQ2hhaW5JZAAPbWFpbkNoYWluSGVpZ2h0CAULJHQwNTg4MTU5NDcCXzEAEm1haW5DaGFpbkxhc3RCbG9jawgFCyR0MDU4ODE1OTQ3Al8yAQllcG9jaE1ldGEBBWVwb2NoBAckbWF0Y2gwCQCiCAEJAQxlcG9jaE1ldGFLZXkBBQVlcG9jaAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAECWZyYWdtZW50cwkAtQkCBQFzBQNTRVAJAJUKAwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQlmcmFnbWVudHMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWZyYWdtZW50cwABCQCRAwIFCWZyYWdtZW50cwACBQR1bml0AAskdDA2MTc4NjY0MgQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAhYoQWRkcmVzcywgSW50LCBTdHJpbmcpBAFtBQckbWF0Y2gwBQFtBAckbWF0Y2gxCQCiCAEFEHRoaXNFcG9jaERhdGFLZXkDCQABAgUHJG1hdGNoMQIGU3RyaW5nBBByYXdUaGlzRXBvY2hEYXRhBQckbWF0Y2gxBA10aGlzRXBvY2hEYXRhCQC1CQIFEHJhd1RoaXNFcG9jaERhdGEFA1NFUAQJdGhpc0Vwb2NoCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNdGhpc0Vwb2NoRGF0YQAACQCVCgMDCQAAAgUJdGhpc0Vwb2NoBQZoZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUNdGhpc0Vwb2NoRGF0YQABBQR1bml0AAACAAkAlQoDBQR1bml0AAACAAAOdGhpc0Vwb2NoTWluZXIIBQskdDA2MTc4NjY0MgJfMQAMdGhpc0Vwb2NoUmVmCAULJHQwNjE3ODY2NDICXzIAEnRoaXNFcG9jaExhc3RCbG9jawgFCyR0MDYxNzg2NjQyAl8zAAxhbGxNaW5lcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMYWxsTWluZXJzS2V5AgAACWFsbE1pbmVycwQHJG1hdGNoMAUMYWxsTWluZXJzU3RyAwkAAAICAAUHJG1hdGNoMAUDbmlsAwkAAQIFByRtYXRjaDACBlN0cmluZwQDcmF3BQckbWF0Y2gwCQC8CQIFA3JhdwUDU0VQCQACAQILTWF0Y2ggZXJyb3IBCWJsb2NrTWV0YQEHYmxvY2tJZAQEbWV0YQkBEUBleHRyTmF0aXZlKDEwNTcpAQkArAICBQpibG9ja01ldGFLBQdibG9ja0lkBAhtZXRhU2l6ZQkAyAEBBQRtZXRhBAtibG9ja0hlaWdodAkAsQkBBQRtZXRhBApibG9ja0Vwb2NoCQCyCQIFBG1ldGEACAQLYmxvY2tQYXJlbnQJAMkBAgkAygECBQRtZXRhABAFD0JMT0NLX0hBU0hfU0laRQQOYmxvY2tHZW5lcmF0b3IJAMkBAgkAygECBQRtZXRhCQBkAgAQBQ9CTE9DS19IQVNIX1NJWkUFDEFERFJFU1NfU0laRQQHY2hhaW5JZAkAsgkCBQRtZXRhCQBkAgkAZAIAEAUPQkxPQ0tfSEFTSF9TSVpFBQxBRERSRVNTX1NJWkUECmJhc2VPZmZzZXQJAGQCCQBkAgAYBQ9CTE9DS19IQVNIX1NJWkUFDEFERFJFU1NfU0laRQQOcmVtYWluaW5nQnl0ZXMJAGUCBQhtZXRhU2l6ZQUKYmFzZU9mZnNldAQXZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2gDCQBnAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQDJAQIJAMoBAgUEbWV0YQUKYmFzZU9mZnNldAUOUk9PVF9IQVNIX1NJWkUBAAQXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgDAwkAAAIFDnJlbWFpbmluZ0J5dGVzAAgGCQBmAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQCyCQIFBG1ldGEJAGQCBQpiYXNlT2Zmc2V0CQDIAQEFF2VsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoAP///////////wEJAJkKBwULYmxvY2tIZWlnaHQFCmJsb2NrRXBvY2gFC2Jsb2NrUGFyZW50BQ5ibG9ja0dlbmVyYXRvcgUHY2hhaW5JZAUXZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2gFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4ARBta0Jsb2NrTWV0YUVudHJ5BwxibG9ja0hhc2hIZXgLYmxvY2tIZWlnaHQOYmxvY2tQYXJlbnRIZXgOYmxvY2tHZW5lcmF0b3IHY2hhaW5JZBplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleBdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAQcZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hCeXRlcwkA3QQBBRplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleAQRcm9vdEhhc2hCeXRlc1NpemUJAMgBAQUcZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hCeXRlcwQNY2hlY2tSb290SGFzaAMDCQAAAgURcm9vdEhhc2hCeXRlc1NpemUAAAYJAAACBRFyb290SGFzaEJ5dGVzU2l6ZQUOUk9PVF9IQVNIX1NJWkUGCQACAQkArAICCQCsAgIJAKwCAgIlVHJhbnNmZXJzIHJvb3QgaGFzaCBzaG91bGQgaGF2ZSAwIG9yIAkApAMBBQ5ST09UX0hBU0hfU0laRQIMIGJ5dGVzLCBnb3QgCQCkAwEFEXJvb3RIYXNoQnl0ZXNTaXplAwkAAAIFDWNoZWNrUm9vdEhhc2gFDWNoZWNrUm9vdEhhc2gEDmJsb2NrTWV0YUJ5dGVzCQDLAQIJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQCaAwEFC2Jsb2NrSGVpZ2h0CQCaAwEFBmhlaWdodAkA3QQBBQ5ibG9ja1BhcmVudEhleAgFDmJsb2NrR2VuZXJhdG9yBWJ5dGVzCQCaAwEFB2NoYWluSWQFHGVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoQnl0ZXMJAJoDAQUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgJAQtCaW5hcnlFbnRyeQIJAKwCAgUKYmxvY2tNZXRhSwUMYmxvY2tIYXNoSGV4BQ5ibG9ja01ldGFCeXRlcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEMbGFzdEhlaWdodEJ5AgVtaW5lcgdjaGFpbklkBAckbWF0Y2gwCQCfCAEJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQdjaGFpbklkBQVtaW5lcgMJAAECBQckbWF0Y2gwAgNJbnQEAWgFByRtYXRjaDAFAWgECWJsb2NrSGFzaAkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAILTGFzdE1pbmVkQnkJAKUIAQUFbWluZXIICQEJYmxvY2tNZXRhAQUJYmxvY2tIYXNoAl8xAAskdDA4OTAzOTg2OQQJaGl0U291cmNlBAckbWF0Y2gwCAUJbGFzdEJsb2NrA3ZyZgMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAN2cmYFByRtYXRjaDAFA3ZyZggFCWxhc3RCbG9jaxNnZW5lcmF0aW9uU2lnbmF0dXJlCgEMcHJvY2Vzc01pbmVyAgRwcmV2BW1pbmVyBAskdDA5MjAxOTI2NAUEcHJldgQJcHJldkRlbGF5CAULJHQwOTIwMTkyNjQCXzEECXByZXZNaW5lcggFCyR0MDkyMDE5MjY0Al8yBBBwcmV2VG90YWxCYWxhbmNlCAULJHQwOTIwMTkyNjQCXzMECnByZXZNaW5lcnMIBQskdDA5MjAxOTI2NAJfNAQMbWluZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQVtaW5lcgQPd2F2ZXNHZW5CYWxhbmNlCAkA7wcBBQxtaW5lckFkZHJlc3MKZ2VuZXJhdGluZwQMbWluZXJCYWxhbmNlCQERZ2VuZXJhdGluZ0JhbGFuY2UBBQxtaW5lckFkZHJlc3MDAwkAZgIFC01JTl9CQUxBTkNFBQ93YXZlc0dlbkJhbGFuY2UGCQBnAgAABQxtaW5lckJhbGFuY2UFBHByZXYECW5leHREZWxheQkAhQcCBQxtaW5lckFkZHJlc3MFDG1pbmVyQmFsYW5jZQMJAGYCBQlwcmV2RGVsYXkFCW5leHREZWxheQkAlgoEBQluZXh0RGVsYXkFBW1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlCQDNCAIFCnByZXZNaW5lcnMFBW1pbmVyCQCWCgQFCXByZXZEZWxheQUJcHJldk1pbmVyCQBkAgUQcHJldlRvdGFsQmFsYW5jZQUMbWluZXJCYWxhbmNlCQDNCAIFCnByZXZNaW5lcnMFBW1pbmVyCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAUHSU5UX01BWAIAAAAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMcHJvY2Vzc01pbmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIADWNvbXB1dGVkRGVsYXkIBQskdDA4OTAzOTg2OQJfMQARY29tcHV0ZWRHZW5lcmF0b3IIBQskdDA4OTAzOTg2OQJfMgAUY29tcHV0ZWRUb3RhbEJhbGFuY2UIBQskdDA4OTAzOTg2OQJfMwAOZmlsdGVyZWRNaW5lcnMIBQskdDA4OTAzOTg2OQJfNAETZ2V0Q2hhaW5MYXN0QmxvY2tJZAEHY2hhaW5JZAgJAQljaGFpbk1ldGEBBQdjaGFpbklkAl8yAAwkdDA5OTM1MTAwNDIJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sADG1jbGJJZ25vcmVkMQgFDCR0MDk5MzUxMDA0MgJfMQAObWFpbkNoYWluRXBvY2gIBQwkdDA5OTM1MTAwNDICXzIAE21haW5DaGFpblBhcmVudEhhc2gIBQwkdDA5OTM1MTAwNDICXzMAEm1haW5DaGFpbkdlbmVyYXRvcggFDCR0MDk5MzUxMDA0MgJfNAEbY2FsY3VsYXRlRmluYWxpemVkQmxvY2tIYXNoAwhjdXJNaW5lcgxjdXJQcmV2RXBvY2gQY3VyTGFzdEJsb2NrSGFzaAQLb2Zmc2V0c18xMDAJALwJAgJkOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OgIABAtoYWxmQmFsYW5jZQkAaQIFFGNvbXB1dGVkVG90YWxCYWxhbmNlAAIKAQRzdGVwAgRwcmV2BG5leHQEDSR0MDEwNDA4MTA0NzIFBHByZXYECXRoaXNFcG9jaAgFDSR0MDEwNDA4MTA0NzICXzEEDHRvdGFsQmFsYW5jZQgFDSR0MDEwNDA4MTA0NzICXzIEDm1heWJlU2FmZUVwb2NoCAUNJHQwMTA0MDgxMDQ3MgJfMwQKcHJldk1pbmVycwgFDSR0MDEwNDA4MTA0NzICXzQEByRtYXRjaDAFDm1heWJlU2FmZUVwb2NoAwkAAQIFByRtYXRjaDACBFVuaXQEDSR0MDEwNTMwMTA2OTYDCQAAAgUJdGhpc0Vwb2NoBQZoZWlnaHQJAJUKAwUIY3VyTWluZXIFDGN1clByZXZFcG9jaAUQY3VyTGFzdEJsb2NrSGFzaAkBBXZhbHVlAQkBCWVwb2NoTWV0YQEFCXRoaXNFcG9jaAQFbWluZXIIBQ0kdDAxMDUzMDEwNjk2Al8xBAlwcmV2RXBvY2gIBQ0kdDAxMDUzMDEwNjk2Al8yBA1sYXN0QmxvY2tIYXNoCAUNJHQwMTA1MzAxMDY5NgJfMwMDCQAAAgUJcHJldkVwb2NoAAAGCQBnAgkAZQIFBmhlaWdodAUJdGhpc0Vwb2NoAGQJAJYKBAUJdGhpc0Vwb2NoBQx0b3RhbEJhbGFuY2UFDWxhc3RCbG9ja0hhc2gFCWFsbE1pbmVycwQNJHQwMTA4NTAxMTA1MgMJAQ9jb250YWluc0VsZW1lbnQCBQpwcmV2TWluZXJzBQVtaW5lcgkAlAoCBQx0b3RhbEJhbGFuY2UFCnByZXZNaW5lcnMJAJQKAgkAZAIFDHRvdGFsQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUFbWluZXIJAMwIAgUFbWluZXIFCnByZXZNaW5lcnMED25ld1RvdGFsQmFsYW5jZQgFDSR0MDEwODUwMTEwNTICXzEECW5ld01pbmVycwgFDSR0MDEwODUwMTEwNTICXzIDCQBmAgUPbmV3VG90YWxCYWxhbmNlBQtoYWxmQmFsYW5jZQkAlgoEBQl0aGlzRXBvY2gFD25ld1RvdGFsQmFsYW5jZQUNbGFzdEJsb2NrSGFzaAUJYWxsTWluZXJzCQCWCgQFCXByZXZFcG9jaAUPbmV3VG90YWxCYWxhbmNlBQR1bml0BQluZXdNaW5lcnMFBHByZXYEDSR0MDExMjg1MTE0MDMKAAIkbAULb2Zmc2V0c18xMDAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQFBmhlaWdodAAABQR1bml0BQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBHN0ZXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDEwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkBA1mYWxsYmFja0Vwb2NoCAUNJHQwMTEyODUxMTQwMwJfMQQMdG90YWxCYWxhbmNlCAUNJHQwMTEyODUxMTQwMwJfMgQVZmluYWxpemVkQmxvY2tIYXNoT3B0CAUNJHQwMTEyODUxMTQwMwJfMwQGbWluZXJzCAUNJHQwMTEyODUxMTQwMwJfNAQHJG1hdGNoMAUVZmluYWxpemVkQmxvY2tIYXNoT3B0AwkAAQIFByRtYXRjaDACBlN0cmluZwQSZmluYWxpemVkQmxvY2tIYXNoBQckbWF0Y2gwBRJmaW5hbGl6ZWRCbG9ja0hhc2gICQEFdmFsdWUBCQEJZXBvY2hNZXRhAQUNZmFsbGJhY2tFcG9jaAJfMwERc3VwcG9ydGluZ0JhbGFuY2UBB2NoYWluSWQKAQphZGRCYWxhbmNlAgNhY2MMZ2VuZXJhdG9yU3RyBA0kdDAxMTY3MzExNzA5BQNhY2MEDHRvdGFsQmFsYW5jZQgFDSR0MDExNjczMTE3MDkCXzEECmdlbmVyYXRvcnMIBQ0kdDAxMTY3MzExNzA5Al8yBAlnZW5lcmF0b3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDGdlbmVyYXRvclN0cgMJAQ9jb250YWluc0VsZW1lbnQCBQpnZW5lcmF0b3JzBQlnZW5lcmF0b3IFA2FjYwQHYmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUJZ2VuZXJhdG9yCQCUCgIJAGQCBQx0b3RhbEJhbGFuY2UFB2JhbGFuY2UJAM0IAgUKZ2VuZXJhdG9ycwUJZ2VuZXJhdG9yBA1hbGxHZW5lcmF0b3JzCQC8CQIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAUDU0VQBA0kdDAxMjAzMTEyMDk2CgACJGwFDWFsbEdlbmVyYXRvcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQphZGRCYWxhbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhVMaXN0IHNpemUgZXhjZWVkcyAxMDAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQBiAGMAZAQHYmFsYW5jZQgFDSR0MDEyMDMxMTIwOTYCXzEEAl9nCAUNJHQwMTIwMzExMjA5NgJfMgUHYmFsYW5jZQEPaXNDb250cmFjdFNldHVwAAkBCWlzRGVmaW5lZAEJAJ8IAQUObWluZXJSZXdhcmRLZXkBEWVuc3VyZU1pbmluZ0Vwb2NoAQlnZW5lcmF0b3IDCQECIT0CCQClCAEFCWdlbmVyYXRvcgURY29tcHV0ZWRHZW5lcmF0b3IJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJANgEAQgFCWdlbmVyYXRvcgVieXRlcwIbIGlzIG5vdCBhbGxvd2VkIHRvIG1pbmUgaW4gCQCkAwEFBmhlaWdodAIRIGVwb2NoLiBFeHBlY3RlZCAFEWNvbXB1dGVkR2VuZXJhdG9yBQR1bml0ARJpc1JlZmVyZW5jZUNvcnJlY3QCCXJlZmVyZW5jZQlsYXN0QmxvY2sDCQAAAgUJcmVmZXJlbmNlBQlsYXN0QmxvY2sFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICAjBFeHBlY3RlZCBhIHJlZmVyZW5jZSB0byB0aGUgY2hhaW4gbGFzdCBibG9jazogMHgFCWxhc3RCbG9jawIJLiBHb3Q6IDB4BQlyZWZlcmVuY2UBD2NoYWluSXNJbmFjdGl2ZQEHY2hhaW5JZAQMZmlyc3RCbG9ja0lkCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkBBRmaXJzdFZhbGlkQWx0Q2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQAAAwkAZgIFFGZpcnN0VmFsaWRBbHRDaGFpbklkBQdjaGFpbklkBgkAZgIICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzEICQEJYmxvY2tNZXRhAQUMZmlyc3RCbG9ja0lkAl8xAQxtaW5lckNoYWluSWQBBW1pbmVyCQELdmFsdWVPckVsc2UCCQCfCAEJAQ9taW5lckNoYWluSWRLZXkBBQVtaW5lcgkAnwgBCQCsAgICCWNoYWluSWRPZgkApQgBBQVtaW5lcgEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCWdlbmVyYXRvcg9leHBlY3RlZENoYWluSWQQY2hlY2tIZWlnaHRCbG9jawQPaGVpZ2h0SXNDb3JyZWN0BAckbWF0Y2gwBRBjaGVja0hlaWdodEJsb2NrAwkAAQIFByRtYXRjaDACBlN0cmluZwQJYmxvY2tIYXNoBQckbWF0Y2gwBBRsYXN0TWluZWRCbG9ja0hlaWdodAkBDGxhc3RIZWlnaHRCeQIFCWdlbmVyYXRvcgULbWFpbkNoYWluSWQJAGYCCQBkAggJAQlibG9ja01ldGEBBQlibG9ja0hhc2gCXzEAAQUUbGFzdE1pbmVkQmxvY2tIZWlnaHQGBAckbWF0Y2gwCQEMbWluZXJDaGFpbklkAQUJZ2VuZXJhdG9yAwkAAQIFByRtYXRjaDACA0ludAQJY3VycmVudElkBQckbWF0Y2gwAwMJAAACBQljdXJyZW50SWQFD2V4cGVjdGVkQ2hhaW5JZAYDCQEPY2hhaW5Jc0luYWN0aXZlAQUJY3VycmVudElkBQ9oZWlnaHRJc0NvcnJlY3QHBQR1bml0CQACAQkArAICAhxtaW5lciBpcyBtaW5pbmcgb3RoZXIgY2hhaW4gCQCkAwEFCWN1cnJlbnRJZAUEdW5pdAESZW5zdXJlQ29ycmVjdEVwb2NoAQVlcG9jaAMJAAACBQVlcG9jaAUGaGVpZ2h0BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIaRXhwZWN0ZWQgYmxvY2sgZnJvbSBlcG9jaCAJAKQDAQUGaGVpZ2h0AgYuIEdvdCAJAKQDAQUFZXBvY2gBDGFkZFN1cHBvcnRlcgIHY2hhaW5JZAlnZW5lcmF0b3IEDXN1cHBvcnRlcnNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAQKc3VwcG9ydGVycwkAvAkCBQ1zdXBwb3J0ZXJzU3RyBQNTRVADCQEPY29udGFpbnNFbGVtZW50AgUKc3VwcG9ydGVycwkApQgBBQlnZW5lcmF0b3IFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQENc3VwcG9ydGVyc0tleQEFB2NoYWluSWQJAKwCAgkArAICBQ1zdXBwb3J0ZXJzU3RyBQNTRVAJAKUIAQUJZ2VuZXJhdG9yBQNuaWwBCXNldE9yRmFpbAIFZmxhZ3MFaW5kZXgDCQBmAgAABQVpbmRleAkAAgEJAKwCAgIiQ2FuJ3Qgd2l0aGRyYXcgYXQgbmVnYXRpdmUgaW5kZXg6IAkApAMBBQVpbmRleAQJZmxhZ3NTaXplCQCxAgEFBWZsYWdzAwkAZwIFBWluZGV4BQlmbGFnc1NpemUECWFkZFplcm9lcwkAZQIFBWluZGV4BQlmbGFnc1NpemUDCQBmAgUJYWRkWmVyb2VzCQCxAgEFCXplcm9lc1N0cgkAAgEJAKwCAgkArAICAgpDYW4ndCBhZGQgCQCkAwEFCWFkZFplcm9lcwIlIGVtcHR5IGZsYWdzLiBDb250YWN0IHdpdGggZGV2ZWxvcGVycwkArAICCQCsAgIFBWZsYWdzCQCvAgIFCXplcm9lc1N0cgUJYWRkWmVyb2VzAgExBAR0YWlsCQCwAgIFBWZsYWdzBQVpbmRleAQHYXRJbmRleAkArwICBQR0YWlsAAEDCQAAAgUHYXRJbmRleAIBMAkArAICCQCsAgIJAK8CAgUFZmxhZ3MFBWluZGV4AgExCQCwAgIFBHRhaWwAAQkAAgEJAKwCAgkArAICAgpUcmFuc2ZlciAjCQCkAwEFBWluZGV4AhcgaGFzIGJlZW4gYWxyZWFkeSB0YWtlbgERdmFsaWRhdGVCbG9ja0hhc2gBBmhleFN0cgQMZGVjb2RlZEJ5dGVzCQDdBAEFBmhleFN0cgMJAQIhPQIJAMgBAQUMZGVjb2RlZEJ5dGVzACAJAAIBAhdpbnZhbGlkIGJsb2NrIGlkIGxlbmd0aAUGaGV4U3RyAR1nZXRVcGRhdGVGaW5hbGl6ZWRCbG9ja0FjdGlvbgMGY2FsbGVyD25ld0Jsb2NrSGFzaEhleAlwcmV2RXBvY2gEF2N1ckZpbmFsaXplZEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFEWZpbmFsaXplZEJsb2NrS2V5Al8xBBVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gJARtjYWxjdWxhdGVGaW5hbGl6ZWRCbG9ja0hhc2gDBQZjYWxsZXIFCXByZXZFcG9jaAUPbmV3QmxvY2tIYXNoSGV4AwMJAAACBRVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gFD25ld0Jsb2NrSGFzaEhleAYJAGYCCAkBCWJsb2NrTWV0YQEFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAJfMQUXY3VyRmluYWxpemVkQmxvY2tIZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgURZmluYWxpemVkQmxvY2tLZXkFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAUDbmlsBQNuaWwJAWkBDmFwcGVuZEJsb2NrX3YzBAxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4GmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BAtjaGVja0NhbGxlcgMJAAACBQ50aGlzRXBvY2hNaW5lcggFAWkMb3JpZ2luQ2FsbGVyBgQHJG1hdGNoMAUOdGhpc0Vwb2NoTWluZXIDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQKZXBvY2hNaW5lcgUHJG1hdGNoMAkAAgEJAKwCAgI5bm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGV4cGVjdGVkIGZyb20gCQClCAEFCmVwb2NoTWluZXIJAAIBAkBub3QgYWxsb3dlZCB0byBmb3JnZSBibG9ja3MgaW4gdGhpcyBlcG9jaCwgZXBvY2ggbWluZXIgaXMgYWJzZW50AwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQHY2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkBDG1pbmVyQ2hhaW5JZAEIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQEDSR0MDE2MjQxMTYyOTIJAQljaGFpbk1ldGEBBQdjaGFpbklkBAtjaGFpbkhlaWdodAgFDSR0MDE2MjQxMTYyOTICXzEEC2xhc3RCbG9ja0lkCAUNJHQwMTYyNDExNjI5MgJfMgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFC2xhc3RCbG9ja0lkAwkAAAIFDmNoZWNrUmVmZXJlbmNlBQ5jaGVja1JlZmVyZW5jZQQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzcFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BwMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMEDm5ld0NoYWluSGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQtsYXN0QmxvY2tJZAgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkBRplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleAUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQdjaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCCQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQkBBXZhbHVlAQUOdGhpc0Vwb2NoTWluZXIFA1NFUAkApAMBBQx0aGlzRXBvY2hSZWYFA1NFUAUMYmxvY2tIYXNoSGV4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQESZXh0ZW5kTWFpbkNoYWluX3YzBQxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4BWVwb2NoGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFBWVwb2NoAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFBHVuaXQDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFEm1haW5DaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al83BRdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQ5tYWluQ2hhaW5FcG9jaAUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkAwkAAAIFDXRoaXNFcG9jaE1ldGEFDXRoaXNFcG9jaE1ldGEEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFDm1haW5DaGFpbkVwb2NoBA5uZXdDaGFpbkhlaWdodAkAZAIFD21haW5DaGFpbkhlaWdodAABCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BRJtYWluQ2hhaW5MYXN0QmxvY2sIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4BRdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFC21haW5DaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQttYWluQ2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFC21haW5DaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIFDXRoaXNFcG9jaE1ldGEFA25pbAUUdXBkYXRlRmluYWxpemVkQmxvY2sJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEQc3RhcnRBbHRDaGFpbl92MwUMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAVlcG9jaBplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleBdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA0kdDAxODcxNTE4ODM3CQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4BA5yZWZDaGFpbkhlaWdodAgFDSR0MDE4NzE1MTg4MzcCXzEECHJlZkVwb2NoCAUNJHQwMTg3MTUxODgzNwJfMgQGcmVmUmVmCAUNJHQwMTg3MTUxODgzNwJfMwQMcmVmR2VuZXJhdG9yCAUNJHQwMTg3MTUxODgzNwJfNAQLcmVmSWdub3JlZDUIBQ0kdDAxODcxNTE4ODM3Al81BAtyZWZJZ25vcmVkNggFDSR0MDE4NzE1MTg4MzcCXzYEEHJlZlRyYW5zZmVySW5kZXgIBQ0kdDAxODcxNTE4ODM3Al83BA5maW5hbGl6ZWRFcG9jaAgJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMgQIZXBvY2hSZWYDCQBnAgUIcmVmRXBvY2gFDmZpbmFsaXplZEVwb2NoBQhyZWZFcG9jaAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIjQ2FuIG5vdCBzdGFydCBhbHQgY2hhaW4gZnJvbSBlcG9jaCAJAKQDAQUIcmVmRXBvY2gCCCwgZXBvY2ggCQCkAwEFDmZpbmFsaXplZEVwb2NoAg0gaXMgZmluYWxpemVkBApjaGVja0NoYWluCQEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCAUBaQxvcmlnaW5DYWxsZXIFC21haW5DaGFpbklkBQxyZWZlcmVuY2VIZXgDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwUQcmVmVHJhbnNmZXJJbmRleAUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgGAwkAAAIFDmNoZWNrVHJhbnNmZXJzBQ5jaGVja1RyYW5zZmVycwQKbmV3Q2hhaW5JZAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObGFzdENoYWluSWRLZXkAAAABBA5uZXdDaGFpbkhlaWdodAkAZAIFDnJlZkNoYWluSGVpZ2h0AAEEDXRoaXNFcG9jaE1ldGEEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIEVW5pdAkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKwCAgkArAICCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUDU0VQCQCkAwEFCGVwb2NoUmVmBQNTRVAFDGJsb2NrSGFzaEhleAQFb3RoZXIFByRtYXRjaDAJAAIBAhVFcG9jaCBhbHJlYWR5IHN0YXJ0ZWQEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yCQDMCAIFDXRoaXNFcG9jaE1ldGEJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQxyZWZlcmVuY2VIZXgIBQFpDG9yaWdpbkNhbGxlcgUKbmV3Q2hhaW5JZAUaZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hIZXgFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFCm5ld0NoYWluSWQFDGJsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFCm5ld0NoYWluSWQFDm5ld0NoYWluSGVpZ2h0BQxibG9ja0hhc2hIZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9taW5lckNoYWluSWRLZXkBCAUBaQxvcmlnaW5DYWxsZXIFCm5ld0NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQpuZXdDaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgULbWFpbkNoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQpuZXdDaGFpbklkCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObGFzdENoYWluSWRLZXkFCm5ld0NoYWluSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFleHRlbmRBbHRDaGFpbl92MwYHY2hhaW5JZAxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4BWVwb2NoGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFBWVwb2NoAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gEE2NoYWluRmlyc3RCbG9ja01ldGEJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkBApjaGVja0NoYWluCQEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCAUBaQxvcmlnaW5DYWxsZXIFB2NoYWluSWQJANwEAQgFE2NoYWluRmlyc3RCbG9ja01ldGECXzMDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQNJHQwMjExODEyMTIzNQkBCWNoYWluTWV0YQEFB2NoYWluSWQEC2NoYWluSGVpZ2h0CAUNJHQwMjExODEyMTIzNQJfMQQOY2hhaW5MYXN0QmxvY2sIBQ0kdDAyMTE4MTIxMjM1Al8yBA5jaGVja1JlZmVyZW5jZQkBEmlzUmVmZXJlbmNlQ29ycmVjdAIFDHJlZmVyZW5jZUhleAUOY2hhaW5MYXN0QmxvY2sDCQAAAgUOY2hlY2tSZWZlcmVuY2UFDmNoZWNrUmVmZXJlbmNlBA5jaGVja1RyYW5zZmVycwkBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDCAkBCWJsb2NrTWV0YQEFDHJlZmVyZW5jZUhleAJfNwUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgGAwkAAAIFDmNoZWNrVHJhbnNmZXJzBQ5jaGVja1RyYW5zZmVycwQObmV3Q2hhaW5IZWlnaHQJAGQCBQtjaGFpbkhlaWdodAABBAlwcmV2RXBvY2gICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al8yBBN1cGRhdGVNYWluQ2hhaW5EYXRhAwkAZgIJARFzdXBwb3J0aW5nQmFsYW5jZQEFB2NoYWluSWQJAGkCBRRjb21wdXRlZFRvdGFsQmFsYW5jZQACBAtsYXN0Q2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5sYXN0Q2hhaW5JZEtleQAABBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFCXByZXZFcG9jaAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBBQttYWluQ2hhaW5JZAgFE2NoYWluRmlyc3RCbG9ja01ldGECXzEJAMwIAgkBDEludGVnZXJFbnRyeQIFDm1haW5DaGFpbklkS2V5BQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQkAZAIFC2xhc3RDaGFpbklkAAEFA25pbAUUdXBkYXRlRmluYWxpemVkQmxvY2sFA25pbAQNdGhpc0Vwb2NoTWV0YQQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAgRVbml0CQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQNTRVAJAKQDAQUJcHJldkVwb2NoBQNTRVAFDGJsb2NrSGFzaEhleAQFb3RoZXIFByRtYXRjaDAJAAIBAhVFcG9jaCBhbHJlYWR5IHN0YXJ0ZWQDCQAAAgUNdGhpc0Vwb2NoTWV0YQUNdGhpc0Vwb2NoTWV0YQQOY2hlY2tHZW5lcmF0b3IJARFlbnN1cmVNaW5pbmdFcG9jaAEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQ5jaGVja0dlbmVyYXRvcgUOY2hlY2tHZW5lcmF0b3IEHXVwZGF0ZU1haW5DaGFpbkxhc3RNaW5lZEJsb2NrAwMJAAACBRN1cGRhdGVNYWluQ2hhaW5EYXRhBQNuaWwJAQIhPQIJAQt2YWx1ZU9yRWxzZQIJAQxtaW5lckNoYWluSWQBCAUBaQxvcmlnaW5DYWxsZXIAAAUHY2hhaW5JZAcJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQttYWluQ2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMQUDbmlsBQNuaWwJAM4IAgkAzggCCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQxyZWZlcmVuY2VIZXgIBQFpDG9yaWdpbkNhbGxlcgUHY2hhaW5JZAUaZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hIZXgFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCBQ10aGlzRXBvY2hNZXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAUDbmlsBRN1cGRhdGVNYWluQ2hhaW5EYXRhCQEMYWRkU3VwcG9ydGVyAgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBR11cGRhdGVNYWluQ2hhaW5MYXN0TWluZWRCbG9jawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRqb2luAQ1yZXdhcmRBZGRyZXNzCgEdZW5zdXJlTm90T3ZlcnJpZGVPdGhlck1pbmVyUGsBDGVsQWRkcmVzc0hleAQHJG1hdGNoMAkAoQgBCQEKbWluZXJQa0tleQEFDGVsQWRkcmVzc0hleAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACBQJwawgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIRRUwgbWluZXIgYWRkcmVzcyAFDGVsQWRkcmVzc0hleAIYIGlzIGFscmVhZHkgbGlua2VkIHdpdGggCQDYBAEFAnBrBQR1bml0AwkBASEBCQEPaXNDb250cmFjdFNldHVwAAkAAgECH1RoZSBjb250cmFjdCBoYXMgbm90IHlldCBzZXQgdXADCQBmAgULTUlOX0JBTEFOQ0UICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nCQACAQkArAICCQCsAgIJAKwCAgIhSW5zdWZmaWNpZW50IGdlbmVyYXRpbmcgYmFsYW5jZTogCQCkAwEICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nAgwuIFJlcXVpcmVkOiAJAKQDAQULTUlOX0JBTEFOQ0UDCQECIT0CCQDIAQEFDXJld2FyZEFkZHJlc3MAFAkAAgECJXJld2FyZEFkZHJlc3Mgc2hvdWxkIGJlIGFuIEwyIGFkZHJlc3MDCQBnAgkAkAMBBQlhbGxNaW5lcnMAMgkAAgECD3RvbyBtYW55IG1pbmVycwoBDmNoZWNrRXhpc3RlbmNlAgZleGlzdHMFbWluZXIDBQZleGlzdHMGCQAAAgUFbWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBA1hbHJlYWR5RXhpc3RzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAHCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ5jaGVja0V4aXN0ZW5jZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAwUNYWxyZWFkeUV4aXN0cwUDbmlsBAhuZXdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEEHJld2FyZEFkZHJlc3NIZXgJANwEAQUNcmV3YXJkQWRkcmVzcwQFY2hlY2sJAR1lbnN1cmVOb3RPdmVycmlkZU90aGVyTWluZXJQawEFEHJld2FyZEFkZHJlc3NIZXgDCQAAAgUFY2hlY2sFBWNoZWNrBAluZXdNaW5lcnMDCQAAAgkAkAMBBQlhbGxNaW5lcnMAAAUIbmV3TWluZXIJAKwCAgkArAICBQxhbGxNaW5lcnNTdHIFA1NFUAUIbmV3TWluZXIEGGRlbGV0ZU9sZFJld2FyZEFkZHJlc3NQawQHJG1hdGNoMAkAoggBCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIDCQABAgUHJG1hdGNoMAIGU3RyaW5nBApvbGRBZGRyZXNzBQckbWF0Y2gwAwkAAAIFCm9sZEFkZHJlc3MJANwEAQUNcmV3YXJkQWRkcmVzcwUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQptaW5lclBrS2V5AQUKb2xkQWRkcmVzcwUDbmlsBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQxhbGxNaW5lcnNLZXkFCW5ld01pbmVycwkAzAgCCQELU3RyaW5nRW50cnkCCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIJAKwCAgICMHgFEHJld2FyZEFkZHJlc3NIZXgJAMwIAgkBC0JpbmFyeUVudHJ5AgkBCm1pbmVyUGtLZXkBBRByZXdhcmRBZGRyZXNzSGV4CAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFA25pbAUYZGVsZXRlT2xkUmV3YXJkQWRkcmVzc1BrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBWxlYXZlAAQMbGVhdmluZ01pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgoBEHNraXBMZWF2aW5nTWluZXICA2FjYwVtaW5lcgMJAAACBQVtaW5lcgUMbGVhdmluZ01pbmVyBQNhY2MJAM0IAgUDYWNjBQVtaW5lcgQPcmVtYWluaW5nTWluZXJzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQc2tpcExlYXZpbmdNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyBA1yZXdhcmRBZGRyS2V5CQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUMbGVhdmluZ01pbmVyBBFwcmV2UmV3YXJkQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDXJld2FyZEFkZHJLZXkCFm1pbmVyIGhhcyBuZXZlciBqb2luZWQDCQAAAgURcHJldlJld2FyZEFkZHJlc3MFEXByZXZSZXdhcmRBZGRyZXNzAwkAAAIFDnRoaXNFcG9jaE1pbmVyCAUBaQxvcmlnaW5DYWxsZXIJAAIBAhxkZXNpZ25hdGVkIG1pbmVyIGNhbid0IGxlYXZlCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQkAugkCBQ9yZW1haW5pbmdNaW5lcnMFA1NFUAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHRyYW5zZmVyARBkZXN0RWxBZGRyZXNzSGV4BAxjaGVja0FkZHJlc3MDCQAAAgkAsQIBBRBkZXN0RWxBZGRyZXNzSGV4BRRFVEhfQUREUkVTU19TVFJfU0laRQkA3QQBBRBkZXN0RWxBZGRyZXNzSGV4CQACAQkArAICCQCsAgIJAKwCAgIUQWRkcmVzcyBzaG91bGQgaGF2ZSAJAKQDAQUURVRIX0FERFJFU1NfU1RSX1NJWkUCESBjaGFyYWN0ZXJzLCBnb3QgCQCkAwEJALECAQUQZGVzdEVsQWRkcmVzc0hleAMJAAACBQxjaGVja0FkZHJlc3MFDGNoZWNrQWRkcmVzcwQMY2hlY2tQYXltZW50AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAIBCQCsAgICL0V4cGVjdGVkIG9uZSBwYXltZW50IGFzIGEgdHJhbnNmZXIgYW1vdW50LCBnb3QgCQCkAwEJAJADAQgFAWkIcGF5bWVudHMDCQAAAgUMY2hlY2tQYXltZW50BQxjaGVja1BheW1lbnQECnRva2VuSWRTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkEB3Rva2VuSWQJANkEAQUKdG9rZW5JZFN0cgQBdAkAkQMCCAUBaQhwYXltZW50cwAABAxjaGVja0Fzc2V0SWQEByRtYXRjaDAIBQF0B2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQHYXNzZXRJZAUHJG1hdGNoMAMJAAACBQdhc3NldElkBQd0b2tlbklkBgkAAgEJAKwCAgkArAICCQCsAgICCUV4cGVjdGVkIAUKdG9rZW5JZFN0cgIVIGluIHRoZSBwYXltZW50LCBnb3QgCQDYBAEFB2Fzc2V0SWQJAAIBCQCsAgIJAKwCAgIJRXhwZWN0ZWQgBQp0b2tlbklkU3RyAhogaW4gdGhlIHBheW1lbnQsIGdvdCBXYXZlcwMJAAACBQxjaGVja0Fzc2V0SWQFDGNoZWNrQXNzZXRJZAQJbGFzdEluZGV4CAkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawJfNwQJcXVldWVTaXplCQBlAgUUbmF0aXZlVHJhbnNmZXJzQ291bnQFCWxhc3RJbmRleAQPY2hlY2tRdWV1ZUxpbWl0AwkAZgIAoAEFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AMCEPQUJcXVldWVTaXplAwkAZgIAwAwFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AICt4gQFCXF1ZXVlU2l6ZQMJAGYCAIAZBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdACAwtcvBQlxdWV1ZVNpemUDCQBmAgCAMgUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAgJTr3AMFCXF1ZXVlU2l6ZQkAAgEJAKwCAgkArAICAiNUcmFuc2ZlcnMgZGVuaWVkIGZvciBxdWV1ZSBzaXplIG9mIAkApAMBBQlxdWV1ZVNpemUCKC4gV2FpdCB1bnRpbCBjdXJyZW50IHRyYW5zZmVycyBwcm9jZXNzZWQDCQAAAgUPY2hlY2tRdWV1ZUxpbWl0BQ9jaGVja1F1ZXVlTGltaXQJAMwIAgkBDEludGVnZXJFbnRyeQIFF25hdGl2ZVRyYW5zZmVyc0NvdW50S2V5CQBkAgUUbmF0aXZlVHJhbnNmZXJzQ291bnQAAQkAzAgCCQEVbWtOYXRpdmVUcmFuc2ZlckVudHJ5AwUUbmF0aXZlVHJhbnNmZXJzQ291bnQFEGRlc3RFbEFkZHJlc3NIZXgIBQF0BmFtb3VudAkAzAgCCQEEQnVybgIFB3Rva2VuSWQIBQF0BmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHdpdGhkcmF3BAxibG9ja0hhc2hIZXgLbWVya2xlUHJvb2YUdHJhbnNmZXJJbmRleEluQmxvY2sGYW1vdW50BBF3aXRoZHJhd0Jsb2NrTWV0YQkBCWJsb2NrTWV0YQEFDGJsb2NrSGFzaEhleAQTd2l0aGRyYXdCbG9ja0hlaWdodAgFEXdpdGhkcmF3QmxvY2tNZXRhAl8xBBRmaW5hbGl6ZWRCbG9ja0hlaWdodAgJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMQQYbWFpbkNoYWluTGFzdEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawJfMQMJAGYCBRN3aXRoZHJhd0Jsb2NrSGVpZ2h0BRRmaW5hbGl6ZWRCbG9ja0hlaWdodAkAAgEJAKwCAgkArAICCQCsAgICCkVMIGJsb2NrICMJAKQDAQUTd2l0aGRyYXdCbG9ja0hlaWdodAItIGlzIG5vdCBmaW5hbGl6ZWQuIFRoZSBjdXJyZW50IGZpbmFsaXplZCBpcyAjCQCkAwEFFGZpbmFsaXplZEJsb2NrSGVpZ2h0AwkBAiE9AgkAkAMBBQttZXJrbGVQcm9vZgUUV0lUSERSQVdfUFJPT0ZTX1NJWkUJAAIBCQCsAgIJAKwCAgkArAICAglFeHBlY3RlZCAJAKQDAQUUV0lUSERSQVdfUFJPT0ZTX1NJWkUCDSBwcm9vZnMsIGdvdCAJAKQDAQkAkAMBBQttZXJrbGVQcm9vZgMJAGYCAAAFFHRyYW5zZmVySW5kZXhJbkJsb2NrCQACAQkArAICAjNUcmFuc2ZlciBpbmRleCBpbiBibG9jayBzaG91bGQgYmUgbm9ubmVnYXRpdmUsIGdvdCAJAKQDAQUUdHJhbnNmZXJJbmRleEluQmxvY2sDCQBnAgAABQZhbW91bnQJAAIBCQCsAgICH0Ftb3VudCBzaG91bGQgYmUgcG9zaXRpdmUsIGdvdCAJAKQDAQUGYW1vdW50BBR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAgFEXdpdGhkcmF3QmxvY2tNZXRhAl81BAtpc01haW5DaGFpbgkAAAIFFHdpdGhkcmF3QmxvY2tDaGFpbklkBQttYWluQ2hhaW5JZAQScmVsYXRlc1RvTWFpbkNoYWluBAckbWF0Y2gwCQCfCAEJARRjaGFpbkZvcmtlZEhlaWdodEtleQEFFHdpdGhkcmF3QmxvY2tDaGFpbklkAwkAAQIFByRtYXRjaDACA0ludAQMZm9ya2VkSGVpZ2h0BQckbWF0Y2gwCQBmAgUMZm9ya2VkSGVpZ2h0BRN3aXRoZHJhd0Jsb2NrSGVpZ2h0CQACAQkArAICCQCsAgIJAKwCAgUMYmxvY2tIYXNoSGV4Ah0gaXMgb24gYW4gYWx0ZXJuYXRpdmUgY2hhaW4gIwkApAMBBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAI4IHRoYXQgd2FzIG5vdCBhcHByb3ZlZCBieSBtYWpvcml0eS4gV2FpdCBmb3Igc29tZSBibG9ja3MDAwULaXNNYWluQ2hhaW4GBRJyZWxhdGVzVG9NYWluQ2hhaW4ECXJlY2lwaWVudAgFAWkMb3JpZ2luQ2FsbGVyBA9yZWNpcGllbnRQa0hhc2gJAMkBAgkAygECCAUJcmVjaXBpZW50BWJ5dGVzAAIFFFBVQkxJQ19LRVlfSEFTSF9TSVpFBA96ZXJvQW1vdW50Qnl0ZXMBLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAthbW91bnRCeXRlcwkAmgMBBQZhbW91bnQEC2VsRXZlbnREYXRhCQDLAQIJAMsBAgUPcmVjaXBpZW50UGtIYXNoCQDJAQIFD3plcm9BbW91bnRCeXRlcwkAZQIJAMgBAQUPemVyb0Ftb3VudEJ5dGVzCQDIAQEFC2Ftb3VudEJ5dGVzBQthbW91bnRCeXRlcwQRZWxFdmVudERhdGFEaWdlc3QJAPAVAQULZWxFdmVudERhdGEEEmNhbGN1bGF0ZWRSb290SGFzaAkAvQUDBQttZXJrbGVQcm9vZgURZWxFdmVudERhdGFEaWdlc3QFFHRyYW5zZmVySW5kZXhJbkJsb2NrBBBleHBlY3RlZFJvb3RIYXNoCAURd2l0aGRyYXdCbG9ja01ldGECXzYDCQAAAgUSY2FsY3VsYXRlZFJvb3RIYXNoBRBleHBlY3RlZFJvb3RIYXNoBAd0b2tlbklkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkEDHRyYW5zZmVyc0tleQkBF2Jsb2NrRWxUb0NsVHJhbnNmZXJzS2V5AQUMYmxvY2tIYXNoSGV4CQDMCAIJAQdSZWlzc3VlAwUHdG9rZW5JZAUGYW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQlyZWNpcGllbnQFBmFtb3VudAUHdG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCBQx0cmFuc2ZlcnNLZXkJAQlzZXRPckZhaWwCCQELdmFsdWVPckVsc2UCCQCiCAEFDHRyYW5zZmVyc0tleQIABRR0cmFuc2ZlckluZGV4SW5CbG9jawUDbmlsCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIURXhwZWN0ZWQgcm9vdCBoYXNoOiAJANwEAQUQZXhwZWN0ZWRSb290SGFzaAIHLCBnb3Q6IAkA3AQBBRJjYWxjdWxhdGVkUm9vdEhhc2gCFS4gRXZlbnQgZGF0YSBkaWdlc3Q6IAkA2gQBBRFlbEV2ZW50RGF0YURpZ2VzdAIfLiBDaGVjayB5b3VyIHdpdGhkcmF3IGFyZ3VtZW50cwkAAgEJAKwCAgkArAICAglFeHBlY3RlZCAFDGJsb2NrSGFzaEhleAIvIHRvIGJlIGVpdGhlciBvbiB0aGUgbWFpbiBjaGFpbiBvciByZWxhdGUgdG8gaXQBaQEFc2V0dXAEE2dlbmVzaXNCbG9ja0hhc2hIZXgRbWluZXJSZXdhcmRJbkd3ZWkZc3Rha2luZ0NvbnRyYWN0QWRkcmVzc0I1OBJlbEJyaWRnZUFkZHJlc3NIZXgDCQEPaXNDb250cmFjdFNldHVwAAkAAgECJFRoZSBjb250cmFjdCBoYXMgYmVlbiBhbHJlYWR5IHNldCB1cAMJAGYCAAAFEW1pbmVyUmV3YXJkSW5Hd2VpCQACAQIkVGhlIG1pbmVyIHJld2FyZCBtdXN0IGJlIG5vbm5lZ2F0aXZlBBBnZW5lc2lzQmxvY2tIYXNoCQDdBAEFE2dlbmVzaXNCbG9ja0hhc2hIZXgEGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUDCQAAAgkAyAEBBRBnZW5lc2lzQmxvY2tIYXNoBQ9CTE9DS19IQVNIX1NJWkUGCQACAQIYV3JvbmcgZ2VuZXNpcyBibG9jayBoYXNoAwkAAAIFGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUFGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUEG3N0YWtpbmdDb250cmFjdEFkZHJlc3NCeXRlcwkA2QQBBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzQjU4BBtjaGVja1N0YWtpbmdDb250cmFjdEFkZHJlc3MDCQAAAgkAyAEBBRtzdGFraW5nQ29udHJhY3RBZGRyZXNzQnl0ZXMFDEFERFJFU1NfU0laRQYJAAIBAh5Xcm9uZyBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3MDCQAAAgUbY2hlY2tTdGFraW5nQ29udHJhY3RBZGRyZXNzBRtjaGVja1N0YWtpbmdDb250cmFjdEFkZHJlc3MEFGNoZWNrRWxCcmlkZ2VBZGRyZXNzAwkAAAIJALECAQUSZWxCcmlkZ2VBZGRyZXNzSGV4BRRFVEhfQUREUkVTU19TVFJfU0laRQkA3QQBBRJlbEJyaWRnZUFkZHJlc3NIZXgJAAIBAhRXcm9uZyBicmlkZ2UgYWRkcmVzcwMJAAACBRRjaGVja0VsQnJpZGdlQWRkcmVzcwUUY2hlY2tFbEJyaWRnZUFkZHJlc3MEB2VtcHR5UGsBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBNnZW5lc2lzTWluZXJBZGRyZXNzCQCnCAEFB2VtcHR5UGsEF2dlbmVzaXNFdGhSZXdhcmRBZGRyZXNzARQAAAAAAAAAAAAAAAAAAAAAAAAAAAQZZ2VuZXNpc0Jsb2NrUmVmZXJlbmNlSGFzaAJAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQFaXNzdWUJAMIIBQIFVU5JVDACDE5hdGl2ZSB0b2tlbgAAAAgGBAd0b2tlbklkCQC4CAEFBWlzc3VlBBBnZW5lc2lzQmxvY2tNZXRhCQEQbWtCbG9ja01ldGFFbnRyeQcFE2dlbmVzaXNCbG9ja0hhc2hIZXgAAAUZZ2VuZXNpc0Jsb2NrUmVmZXJlbmNlSGFzaAUTZ2VuZXNpc01pbmVyQWRkcmVzcwAACQDcBAEBAAD///////////8BCQDMCAIFEGdlbmVzaXNCbG9ja01ldGEJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQAABRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwAAAAAFE2dlbmVzaXNCbG9ja0hhc2hIZXgJAMwIAgkBDEludGVnZXJFbnRyeQIFDm1pbmVyUmV3YXJkS2V5BRFtaW5lclJld2FyZEluR3dlaQkAzAgCCQELU3RyaW5nRW50cnkCBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5BRlzdGFraW5nQ29udHJhY3RBZGRyZXNzQjU4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQClCAEFE2dlbmVzaXNNaW5lckFkZHJlc3MCAywwLAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQELU3RyaW5nRW50cnkCBRFmaW5hbGl6ZWRCbG9ja0tleQUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCBQp0b2tlbklkS2V5CQDYBAEFB3Rva2VuSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUSZWxCcmlkZ2VBZGRyZXNzS2V5CQCsAgICAjB4BRJlbEJyaWRnZUFkZHJlc3NIZXgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgCrM4wQ", "height": 3261511, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 585yRVUw4LP2txC7iF4XgTP7FiiRpxnUKmXgr9oeB4Ni Next: CorJ2yFjR5DscG7W8gj422Pn3wi9hHrPxBd2YZuQbbh5 Diff:
OldNewDifferences
1616 let PUBLIC_KEY_HASH_SIZE = 20
1717
1818 let ROOT_HASH_SIZE = 32
19+
20+let WITHDRAW_PROOFS_SIZE = 10
21+
22+let ETH_ADDRESS_STR_SIZE = 40
1923
2024 let MAX_CL_TO_EL_TRANSFERS = 16
2125
163167
164168 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
165169
166-let $t058215887 = chainMeta(mainChainId)
170+let $t058815947 = chainMeta(mainChainId)
167171
168-let mainChainHeight = $t058215887._1
172+let mainChainHeight = $t058815947._1
169173
170-let mainChainLastBlock = $t058215887._2
174+let mainChainLastBlock = $t058815947._2
171175
172176 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
173177 case s: String =>
178182 }
179183
180184
181-let $t061186582 = match epochMeta(height) {
185+let $t061786642 = match epochMeta(height) {
182186 case m: (Address, Int, String) =>
183187 m
184188 case _ =>
194198 }
195199 }
196200
197-let thisEpochMiner = $t061186582._1
201+let thisEpochMiner = $t061786642._1
198202
199-let thisEpochRef = $t061186582._2
203+let thisEpochRef = $t061786642._2
200204
201-let thisEpochLastBlock = $t061186582._3
205+let thisEpochLastBlock = $t061786642._3
202206
203207 let allMinersStr = valueOrElse(getString(allMinersKey), "")
204208
237241
238242
239243 func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,blockGenerator,chainId,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
240- let blockMetaBytes = ((((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + blockGenerator.bytes) + toBytes(chainId)) + fromBase16String(elToClTransfersRootHashHex)) + toBytes(lastClToElTransferIndex))
241- BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
244+ let elToClTransfersRootHashBytes = fromBase16String(elToClTransfersRootHashHex)
245+ let rootHashBytesSize = size(elToClTransfersRootHashBytes)
246+ let checkRootHash = if (if ((rootHashBytesSize == 0))
247+ then true
248+ else (rootHashBytesSize == ROOT_HASH_SIZE))
249+ then true
250+ else throw(((("Transfers root hash should have 0 or " + toString(ROOT_HASH_SIZE)) + " bytes, got ") + toString(rootHashBytesSize)))
251+ if ((checkRootHash == checkRootHash))
252+ then {
253+ let blockMetaBytes = ((((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + blockGenerator.bytes) + toBytes(chainId)) + elToClTransfersRootHashBytes) + toBytes(lastClToElTransferIndex))
254+ BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
255+ }
256+ else throw("Strict value is not equal to itself.")
242257 }
243258
244259
251266 }
252267
253268
254-let $t084809446 = {
269+let $t089039869 = {
255270 let hitSource = match lastBlock.vrf {
256271 case vrf: ByteVector =>
257272 vrf
259274 lastBlock.generationSignature
260275 }
261276 func processMiner (prev,miner) = {
262- let $t087788841 = prev
263- let prevDelay = $t087788841._1
264- let prevMiner = $t087788841._2
265- let prevTotalBalance = $t087788841._3
266- let prevMiners = $t087788841._4
277+ let $t092019264 = prev
278+ let prevDelay = $t092019264._1
279+ let prevMiner = $t092019264._2
280+ let prevTotalBalance = $t092019264._3
281+ let prevMiners = $t092019264._4
267282 let minerAddress = addressFromStringValue(miner)
268283 let wavesGenBalance = wavesBalance(minerAddress).generating
269284 let minerBalance = generatingBalance(minerAddress)
293308 $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)
294309 }
295310
296-let computedDelay = $t084809446._1
311+let computedDelay = $t089039869._1
297312
298-let computedGenerator = $t084809446._2
313+let computedGenerator = $t089039869._2
299314
300-let computedTotalBalance = $t084809446._3
315+let computedTotalBalance = $t089039869._3
301316
302-let filteredMiners = $t084809446._4
317+let filteredMiners = $t089039869._4
303318
304319 func getChainLastBlockId (chainId) = chainMeta(chainId)._2
305320
306321
307-let $t095129619 = blockMeta(mainChainLastBlock)
322+let $t0993510042 = blockMeta(mainChainLastBlock)
308323
309-let mclbIgnored1 = $t095129619._1
324+let mclbIgnored1 = $t0993510042._1
310325
311-let mainChainEpoch = $t095129619._2
326+let mainChainEpoch = $t0993510042._2
312327
313-let mainChainParentHash = $t095129619._3
328+let mainChainParentHash = $t0993510042._3
314329
315-let mainChainGenerator = $t095129619._4
330+let mainChainGenerator = $t0993510042._4
316331
317332 func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
318333 let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
319334 let halfBalance = (computedTotalBalance / 2)
320335 func step (prev,next) = {
321- let $t0998510049 = prev
322- let thisEpoch = $t0998510049._1
323- let totalBalance = $t0998510049._2
324- let maybeSafeEpoch = $t0998510049._3
325- let prevMiners = $t0998510049._4
336+ let $t01040810472 = prev
337+ let thisEpoch = $t01040810472._1
338+ let totalBalance = $t01040810472._2
339+ let maybeSafeEpoch = $t01040810472._3
340+ let prevMiners = $t01040810472._4
326341 match maybeSafeEpoch {
327342 case _: Unit =>
328- let $t01010710273 = if ((thisEpoch == height))
343+ let $t01053010696 = if ((thisEpoch == height))
329344 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
330345 else value(epochMeta(thisEpoch))
331- let miner = $t01010710273._1
332- let prevEpoch = $t01010710273._2
333- let lastBlockHash = $t01010710273._3
334- if ((prevEpoch == 0))
346+ let miner = $t01053010696._1
347+ let prevEpoch = $t01053010696._2
348+ let lastBlockHash = $t01053010696._3
349+ if (if ((prevEpoch == 0))
350+ then true
351+ else ((height - thisEpoch) >= 100))
335352 then $Tuple4(thisEpoch, totalBalance, lastBlockHash, allMiners)
336353 else {
337- let $t01039810600 = if (containsElement(prevMiners, miner))
354+ let $t01085011052 = if (containsElement(prevMiners, miner))
338355 then $Tuple2(totalBalance, prevMiners)
339356 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
340- let newTotalBalance = $t01039810600._1
341- let newMiners = $t01039810600._2
357+ let newTotalBalance = $t01085011052._1
358+ let newMiners = $t01085011052._2
342359 if ((newTotalBalance > halfBalance))
343360 then $Tuple4(thisEpoch, newTotalBalance, lastBlockHash, allMiners)
344361 else $Tuple4(prevEpoch, newTotalBalance, unit, newMiners)
348365 }
349366 }
350367
351- let $t01083310966 = {
352- let $l = (offsets_100 ++ offsets_100)
368+ let $t01128511403 = {
369+ let $l = offsets_100
353370 let $s = size($l)
354371 let $acc0 = $Tuple4(height, 0, unit, nil)
355372 func $f0_1 ($a,$i) = if (($i >= $s))
358375
359376 func $f0_2 ($a,$i) = if (($i >= $s))
360377 then $a
361- else throw("List size exceeds 200")
378+ else throw("List size exceeds 100")
362379
363- $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($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 101), 102), 103), 104), 105), 106), 107), 108), 109), 110), 111), 112), 113), 114), 115), 116), 117), 118), 119), 120), 121), 122), 123), 124), 125), 126), 127), 128), 129), 130), 131), 132), 133), 134), 135), 136), 137), 138), 139), 140), 141), 142), 143), 144), 145), 146), 147), 148), 149), 150), 151), 152), 153), 154), 155), 156), 157), 158), 159), 160), 161), 162), 163), 164), 165), 166), 167), 168), 169), 170), 171), 172), 173), 174), 175), 176), 177), 178), 179), 180), 181), 182), 183), 184), 185), 186), 187), 188), 189), 190), 191), 192), 193), 194), 195), 196), 197), 198), 199), 200)
380+ $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)
364381 }
365- let fallbackEpoch = $t01083310966._1
366- let totalBalance = $t01083310966._2
367- let finalizedBlockHashOpt = $t01083310966._3
368- let miners = $t01083310966._4
382+ let fallbackEpoch = $t01128511403._1
383+ let totalBalance = $t01128511403._2
384+ let finalizedBlockHashOpt = $t01128511403._3
385+ let miners = $t01128511403._4
369386 match finalizedBlockHashOpt {
370387 case finalizedBlockHash: String =>
371388 finalizedBlockHash
377394
378395 func supportingBalance (chainId) = {
379396 func addBalance (acc,generatorStr) = {
380- let $t01123611272 = acc
381- let totalBalance = $t01123611272._1
382- let generators = $t01123611272._2
397+ let $t01167311709 = acc
398+ let totalBalance = $t01167311709._1
399+ let generators = $t01167311709._2
383400 let generator = addressFromStringValue(generatorStr)
384401 if (containsElement(generators, generator))
385402 then acc
390407 }
391408
392409 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
393- let $t01159411659 = {
410+ let $t01203112096 = {
394411 let $l = allGenerators
395412 let $s = size($l)
396413 let $acc0 = $Tuple2(0, nil)
404421
405422 $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)
406423 }
407- let balance = $t01159411659._1
408- let _g = $t01159411659._2
424+ let balance = $t01203112096._1
425+ let _g = $t01203112096._2
409426 balance
410427 }
411428
525542 if ((checkCaller == checkCaller))
526543 then {
527544 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
528- let $t01580415855 = chainMeta(chainId)
529- let chainHeight = $t01580415855._1
530- let lastBlockId = $t01580415855._2
545+ let $t01624116292 = chainMeta(chainId)
546+ let chainHeight = $t01624116292._1
547+ let lastBlockId = $t01624116292._2
531548 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
532549 if ((checkReference == checkReference))
533550 then {
606623 let checkEpoch = ensureCorrectEpoch(epoch)
607624 if ((checkEpoch == checkEpoch))
608625 then {
609- let $t01827818400 = blockMeta(referenceHex)
610- let refChainHeight = $t01827818400._1
611- let refEpoch = $t01827818400._2
612- let refRef = $t01827818400._3
613- let refGenerator = $t01827818400._4
614- let refIgnored5 = $t01827818400._5
615- let refIgnored6 = $t01827818400._6
616- let refTransferIndex = $t01827818400._7
626+ let $t01871518837 = blockMeta(referenceHex)
627+ let refChainHeight = $t01871518837._1
628+ let refEpoch = $t01871518837._2
629+ let refRef = $t01871518837._3
630+ let refGenerator = $t01871518837._4
631+ let refIgnored5 = $t01871518837._5
632+ let refIgnored6 = $t01871518837._6
633+ let refTransferIndex = $t01871518837._7
617634 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
618635 let epochRef = if ((refEpoch >= finalizedEpoch))
619636 then refEpoch
660677 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
661678 if ((checkChain == checkChain))
662679 then {
663- let $t02074420798 = chainMeta(chainId)
664- let chainHeight = $t02074420798._1
665- let chainLastBlock = $t02074420798._2
680+ let $t02118121235 = chainMeta(chainId)
681+ let chainHeight = $t02118121235._1
682+ let chainLastBlock = $t02118121235._2
666683 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
667684 if ((checkReference == checkReference))
668685 then {
802819 }
803820 let rewardAddrKey = minerRewardAddressKey(leavingMiner)
804821 let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
805- if ((thisEpochMiner == i.originCaller))
806- then throw("designated miner can't leave")
807- else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
822+ if ((prevRewardAddress == prevRewardAddress))
823+ then if ((thisEpochMiner == i.originCaller))
824+ then throw("designated miner can't leave")
825+ else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
826+ else throw("Strict value is not equal to itself.")
808827 }
809828
810829
811830
812831 @Callable(i)
813832 func transfer (destElAddressHex) = {
814- let checkPayment = if ((size(i.payments) == 1))
815- then true
816- else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
817- if ((checkPayment == checkPayment))
833+ let checkAddress = if ((size(destElAddressHex) == ETH_ADDRESS_STR_SIZE))
834+ then fromBase16String(destElAddressHex)
835+ else throw(((("Address should have " + toString(ETH_ADDRESS_STR_SIZE)) + " characters, got ") + toString(size(destElAddressHex))))
836+ if ((checkAddress == checkAddress))
818837 then {
819- let checkDestAddress = if ((size(fromBase16String(destElAddressHex)) == 20))
838+ let checkPayment = if ((size(i.payments) == 1))
820839 then true
821- else throw("Destination address must be a valid ethereum address")
822- if ((checkDestAddress == checkDestAddress))
840+ else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
841+ if ((checkPayment == checkPayment))
823842 then {
824843 let tokenIdStr = getStringValue(tokenIdKey)
825844 let tokenId = fromBase58String(tokenIdStr)
835854 if ((checkAssetId == checkAssetId))
836855 then {
837856 let lastIndex = blockMeta(mainChainLastBlock)._7
838- let queueSize = ((nativeTransfersCount - lastIndex) + 1)
857+ let queueSize = (nativeTransfersCount - lastIndex)
839858 let checkQueueLimit = if ((160 > queueSize))
840859 then amountGtEq(t, 1000000, queueSize)
841860 else if ((1600 > queueSize))
866885 let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
867886 if ((withdrawBlockHeight > finalizedBlockHeight))
868887 then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
869- else {
870- let withdrawBlockChainId = withdrawBlockMeta._5
871- let isMainChain = (withdrawBlockChainId == mainChainId)
872- let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
873- case forkedHeight: Int =>
874- (forkedHeight > withdrawBlockHeight)
875- case _ =>
876- throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
877- }
878- if (if (isMainChain)
879- then true
880- else relatesToMainChain)
881- then {
882- let recipient = i.originCaller
883- let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
884- let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
885- let amountBytes = toBytes(amount)
886- let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
887- let elEventDataDigest = blake2b256_16Kb(elEventData)
888- let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
889- let expectedRootHash = withdrawBlockMeta._6
890- if ((calculatedRootHash == expectedRootHash))
891- then {
892- let tokenId = fromBase58String(getStringValue(tokenIdKey))
893- let transfersKey = blockElToClTransfersKey(blockHashHex)
888+ else if ((size(merkleProof) != WITHDRAW_PROOFS_SIZE))
889+ then throw(((("Expected " + toString(WITHDRAW_PROOFS_SIZE)) + " proofs, got ") + toString(size(merkleProof))))
890+ else if ((0 > transferIndexInBlock))
891+ then throw(("Transfer index in block should be nonnegative, got " + toString(transferIndexInBlock)))
892+ else if ((0 >= amount))
893+ then throw(("Amount should be positive, got " + toString(amount)))
894+ else {
895+ let withdrawBlockChainId = withdrawBlockMeta._5
896+ let isMainChain = (withdrawBlockChainId == mainChainId)
897+ let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
898+ case forkedHeight: Int =>
899+ (forkedHeight > withdrawBlockHeight)
900+ case _ =>
901+ throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
902+ }
903+ if (if (isMainChain)
904+ then true
905+ else relatesToMainChain)
906+ then {
907+ let recipient = i.originCaller
908+ let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
909+ let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
910+ let amountBytes = toBytes(amount)
911+ let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
912+ let elEventDataDigest = blake2b256_16Kb(elEventData)
913+ let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
914+ let expectedRootHash = withdrawBlockMeta._6
915+ if ((calculatedRootHash == expectedRootHash))
916+ then {
917+ let tokenId = fromBase58String(getStringValue(tokenIdKey))
918+ let transfersKey = blockElToClTransfersKey(blockHashHex)
894919 [Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
895- }
896- else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
897- }
898- else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
899- }
920+ }
921+ else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
922+ }
923+ else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
924+ }
900925 }
901926
902927
908933 then throw("The miner reward must be nonnegative")
909934 else {
910935 let genesisBlockHash = fromBase16String(genesisBlockHashHex)
911- let emptyPk = base58'11111111111111111111111111111111'
912- let genesisMinerAddress = addressFromPublicKey(emptyPk)
913- let genesisEthRewardAddress = base58'11111111111111111111'
914- let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
915- let issue = Issue("UNIT0", "Native token", 0, 8, true)
916- let tokenId = calculateAssetId(issue)
917- let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, height, genesisBlockReferenceHash, genesisMinerAddress, 0, toBase16String(base58''), -1)
936+ let checkGenesisBlockHashSize = if ((size(genesisBlockHash) == BLOCK_HASH_SIZE))
937+ then true
938+ else throw("Wrong genesis block hash")
939+ if ((checkGenesisBlockHashSize == checkGenesisBlockHashSize))
940+ then {
941+ let stakingContractAddressBytes = fromBase58String(stakingContractAddressB58)
942+ let checkStakingContractAddress = if ((size(stakingContractAddressBytes) == ADDRESS_SIZE))
943+ then true
944+ else throw("Wrong staking contract address")
945+ if ((checkStakingContractAddress == checkStakingContractAddress))
946+ then {
947+ let checkElBridgeAddress = if ((size(elBridgeAddressHex) == ETH_ADDRESS_STR_SIZE))
948+ then fromBase16String(elBridgeAddressHex)
949+ else throw("Wrong bridge address")
950+ if ((checkElBridgeAddress == checkElBridgeAddress))
951+ then {
952+ let emptyPk = base58'11111111111111111111111111111111'
953+ let genesisMinerAddress = addressFromPublicKey(emptyPk)
954+ let genesisEthRewardAddress = base58'11111111111111111111'
955+ let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
956+ let issue = Issue("UNIT0", "Native token", 0, 8, true)
957+ let tokenId = calculateAssetId(issue)
958+ let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, genesisMinerAddress, 0, toBase16String(base58''), -1)
918959 [genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(stakingContractAddressKey, stakingContractAddressB58), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, ("0x" + elBridgeAddressHex))]
960+ }
961+ else throw("Strict value is not equal to itself.")
962+ }
963+ else throw("Strict value is not equal to itself.")
964+ }
965+ else throw("Strict value is not equal to itself.")
919966 }
920967
921968
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 ADDRESS_SIZE = 26
1515
1616 let PUBLIC_KEY_HASH_SIZE = 20
1717
1818 let ROOT_HASH_SIZE = 32
19+
20+let WITHDRAW_PROOFS_SIZE = 10
21+
22+let ETH_ADDRESS_STR_SIZE = 40
1923
2024 let MAX_CL_TO_EL_TRANSFERS = 16
2125
2226 let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
2327
2428 let thisEpochDataKey = "thisEpochData"
2529
2630 let allMinersKey = "allMiners"
2731
2832 let mainChainIdKey = "mainChainId"
2933
3034 let lastChainIdKey = "lastChainId"
3135
3236 let firstValidAltChainIdKey = "firstValidAltChainId"
3337
3438 let minerRewardKey = "minerReward"
3539
3640 let stakingContractAddressKey = "stakingContractAddress"
3741
3842 let blockMetaK = "block_0x"
3943
4044 let finalizedBlockKey = "finalizedBlock"
4145
4246 let tokenIdKey = "tokenId"
4347
4448 let elBridgeAddressKey = "elBridgeAddress"
4549
4650 let nativeTransfersCountKey = "nativeTransfersCount"
4751
4852 func pad (i) = {
4953 let s = toString(i)
5054 match size(s) {
5155 case _ =>
5256 if ((1 == $match0))
5357 then ("0000000" + s)
5458 else if ((2 == $match0))
5559 then ("000000" + s)
5660 else if ((3 == $match0))
5761 then ("00000" + s)
5862 else if ((4 == $match0))
5963 then ("0000" + s)
6064 else if ((5 == $match0))
6165 then ("000" + s)
6266 else if ((6 == $match0))
6367 then ("00" + s)
6468 else if ((7 == $match0))
6569 then ("0" + s)
6670 else s
6771 }
6872 }
6973
7074
7175 func blockElToClTransfersKey (blockHashHex) = ("elToClTransfers_0x" + blockHashHex)
7276
7377
7478 func epochMetaKey (epoch) = ("epoch_" + pad(epoch))
7579
7680
7781 func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
7882
7983
8084 func chainMetaKey (chainId) = ("chain_" + pad(chainId))
8185
8286
8387 func chainLastHeightKey (chainId,miner) = ((("chain_" + pad(chainId)) + "_") + toString(miner))
8488
8589
8690 func chainForkedHeightKey (chainId) = (("chain_" + pad(chainId)) + "ForkedHeight")
8791
8892
8993 func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
9094
9195
9296 func minerRewardAddressKey (minerAddr) = (("miner_" + minerAddr) + "_RewardAddress")
9397
9498
9599 func minerPkKey (rewardAddress) = (("miner_0x" + rewardAddress) + "_PK")
96100
97101
98102 func minerChainIdKey (miner) = (("miner_" + toString(miner)) + "_ChainId")
99103
100104
101105 let nativeTransfersCount = valueOrElse(getInteger(this, nativeTransfersCountKey), 0)
102106
103107 func nativeTransferKey (index) = ("nativeTransfer_" + toString(index))
104108
105109
106110 func mkNativeTransferEntry (index,destElAddressHex,amount) = StringEntry(nativeTransferKey(index), ((("0x" + destElAddressHex) + SEP) + toString(amount)))
107111
108112
109113 func ensureCorrectTransfers (refTransferIndex,transferIndex,expectReward) = {
110114 let maxTransfers = if (expectReward)
111115 then (MAX_CL_TO_EL_TRANSFERS - 1)
112116 else MAX_CL_TO_EL_TRANSFERS
113117 let actualTransfers = (transferIndex - refTransferIndex)
114118 let checkNumber = if ((actualTransfers > maxTransfers))
115119 then throw(((("Allowed only " + toString(maxTransfers)) + " transfers, got ") + toString(actualTransfers)))
116120 else true
117121 if ((checkNumber == checkNumber))
118122 then if ((transferIndex >= nativeTransfersCount))
119123 then throw(((("Attempt to transfer #" + toString(transferIndex)) + ". Available transfers: ") + toString(nativeTransfersCount)))
120124 else true
121125 else throw("Strict value is not equal to itself.")
122126 }
123127
124128
125129 func amountGtEq (t,gtEq,queueSize) = if ((t.amount >= gtEq))
126130 then true
127131 else throw((((((("Transferring amount " + toString(t.amount)) + " should be >= ") + toString(gtEq)) + " for queue size of ") + toString(queueSize)) + ". Transfer more or wait"))
128132
129133
130134 let stakingContractAddress = match getString(this, stakingContractAddressKey) {
131135 case s: String =>
132136 valueOrErrorMessage(addressFromString(s), ("invalid staking contract address: " + s))
133137 case _ =>
134138 Address(getBinaryValue(this, stakingContractAddressKey))
135139 }
136140
137141 func generatingBalance (address) = match getString(stakingContractAddress, ("%s__" + toString(address))) {
138142 case str: String =>
139143 let paramList = split(str, "__")
140144 let prevHeight = parseIntValue(paramList[1])
141145 let prevBalance = parseIntValue(paramList[2])
142146 let nextHeight = parseIntValue(paramList[3])
143147 let nextBalance = parseIntValue(paramList[4])
144148 if ((height >= nextHeight))
145149 then nextBalance
146150 else if ((height >= prevHeight))
147151 then prevBalance
148152 else 0
149153 case _ =>
150154 0
151155 }
152156
153157
154158 func chainMeta (chainId) = {
155159 let s = getStringValue(chainMetaKey(chainId))
156160 let items = split(s, SEP)
157161 $Tuple2(parseIntValue(items[0]), items[1])
158162 }
159163
160164
161165 func mkChainMetaEntry (chainId,newChainHeight,blockHashHex) = StringEntry(chainMetaKey(chainId), ((toString(newChainHeight) + SEP) + blockHashHex))
162166
163167
164168 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
165169
166-let $t058215887 = chainMeta(mainChainId)
170+let $t058815947 = chainMeta(mainChainId)
167171
168-let mainChainHeight = $t058215887._1
172+let mainChainHeight = $t058815947._1
169173
170-let mainChainLastBlock = $t058215887._2
174+let mainChainLastBlock = $t058815947._2
171175
172176 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
173177 case s: String =>
174178 let fragments = split(s, SEP)
175179 $Tuple3(addressFromStringValue(fragments[0]), parseIntValue(fragments[1]), fragments[2])
176180 case _ =>
177181 unit
178182 }
179183
180184
181-let $t061186582 = match epochMeta(height) {
185+let $t061786642 = match epochMeta(height) {
182186 case m: (Address, Int, String) =>
183187 m
184188 case _ =>
185189 match getString(thisEpochDataKey) {
186190 case rawThisEpochData: String =>
187191 let thisEpochData = split(rawThisEpochData, SEP)
188192 let thisEpoch = parseIntValue(thisEpochData[0])
189193 $Tuple3(if ((thisEpoch == height))
190194 then addressFromStringValue(thisEpochData[1])
191195 else unit, 0, "")
192196 case _ =>
193197 $Tuple3(unit, 0, "")
194198 }
195199 }
196200
197-let thisEpochMiner = $t061186582._1
201+let thisEpochMiner = $t061786642._1
198202
199-let thisEpochRef = $t061186582._2
203+let thisEpochRef = $t061786642._2
200204
201-let thisEpochLastBlock = $t061186582._3
205+let thisEpochLastBlock = $t061786642._3
202206
203207 let allMinersStr = valueOrElse(getString(allMinersKey), "")
204208
205209 let allMiners = match allMinersStr {
206210 case _ =>
207211 if (("" == $match0))
208212 then nil
209213 else if ($isInstanceOf($match0, "String"))
210214 then {
211215 let raw = $match0
212216 split_4C(raw, SEP)
213217 }
214218 else throw("Match error")
215219 }
216220
217221 func blockMeta (blockId) = {
218222 let meta = getBinaryValue((blockMetaK + blockId))
219223 let metaSize = size(meta)
220224 let blockHeight = toInt(meta)
221225 let blockEpoch = toInt(meta, 8)
222226 let blockParent = take(drop(meta, 16), BLOCK_HASH_SIZE)
223227 let blockGenerator = take(drop(meta, (16 + BLOCK_HASH_SIZE)), ADDRESS_SIZE)
224228 let chainId = toInt(meta, ((16 + BLOCK_HASH_SIZE) + ADDRESS_SIZE))
225229 let baseOffset = ((24 + BLOCK_HASH_SIZE) + ADDRESS_SIZE)
226230 let remainingBytes = (metaSize - baseOffset)
227231 let elToClTransfersRootHash = if ((remainingBytes >= ROOT_HASH_SIZE))
228232 then take(drop(meta, baseOffset), ROOT_HASH_SIZE)
229233 else base58''
230234 let lastClToElTransferIndex = if (if ((remainingBytes == 8))
231235 then true
232236 else (remainingBytes > ROOT_HASH_SIZE))
233237 then toInt(meta, (baseOffset + size(elToClTransfersRootHash)))
234238 else -1
235239 $Tuple7(blockHeight, blockEpoch, blockParent, blockGenerator, chainId, elToClTransfersRootHash, lastClToElTransferIndex)
236240 }
237241
238242
239243 func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,blockGenerator,chainId,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
240- let blockMetaBytes = ((((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + blockGenerator.bytes) + toBytes(chainId)) + fromBase16String(elToClTransfersRootHashHex)) + toBytes(lastClToElTransferIndex))
241- BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
244+ let elToClTransfersRootHashBytes = fromBase16String(elToClTransfersRootHashHex)
245+ let rootHashBytesSize = size(elToClTransfersRootHashBytes)
246+ let checkRootHash = if (if ((rootHashBytesSize == 0))
247+ then true
248+ else (rootHashBytesSize == ROOT_HASH_SIZE))
249+ then true
250+ else throw(((("Transfers root hash should have 0 or " + toString(ROOT_HASH_SIZE)) + " bytes, got ") + toString(rootHashBytesSize)))
251+ if ((checkRootHash == checkRootHash))
252+ then {
253+ let blockMetaBytes = ((((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + blockGenerator.bytes) + toBytes(chainId)) + elToClTransfersRootHashBytes) + toBytes(lastClToElTransferIndex))
254+ BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
255+ }
256+ else throw("Strict value is not equal to itself.")
242257 }
243258
244259
245260 func lastHeightBy (miner,chainId) = match getInteger(chainLastHeightKey(chainId, miner)) {
246261 case h: Int =>
247262 h
248263 case _ =>
249264 let blockHash = getStringValue(((("chain" + toString(chainId)) + "LastMinedBy") + toString(miner)))
250265 blockMeta(blockHash)._1
251266 }
252267
253268
254-let $t084809446 = {
269+let $t089039869 = {
255270 let hitSource = match lastBlock.vrf {
256271 case vrf: ByteVector =>
257272 vrf
258273 case _ =>
259274 lastBlock.generationSignature
260275 }
261276 func processMiner (prev,miner) = {
262- let $t087788841 = prev
263- let prevDelay = $t087788841._1
264- let prevMiner = $t087788841._2
265- let prevTotalBalance = $t087788841._3
266- let prevMiners = $t087788841._4
277+ let $t092019264 = prev
278+ let prevDelay = $t092019264._1
279+ let prevMiner = $t092019264._2
280+ let prevTotalBalance = $t092019264._3
281+ let prevMiners = $t092019264._4
267282 let minerAddress = addressFromStringValue(miner)
268283 let wavesGenBalance = wavesBalance(minerAddress).generating
269284 let minerBalance = generatingBalance(minerAddress)
270285 if (if ((MIN_BALANCE > wavesGenBalance))
271286 then true
272287 else (0 >= minerBalance))
273288 then prev
274289 else {
275290 let nextDelay = calculateDelay(minerAddress, minerBalance)
276291 if ((prevDelay > nextDelay))
277292 then $Tuple4(nextDelay, miner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
278293 else $Tuple4(prevDelay, prevMiner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
279294 }
280295 }
281296
282297 let $l = allMiners
283298 let $s = size($l)
284299 let $acc0 = $Tuple4(INT_MAX, "", 0, nil)
285300 func $f0_1 ($a,$i) = if (($i >= $s))
286301 then $a
287302 else processMiner($a, $l[$i])
288303
289304 func $f0_2 ($a,$i) = if (($i >= $s))
290305 then $a
291306 else throw("List size exceeds 50")
292307
293308 $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)
294309 }
295310
296-let computedDelay = $t084809446._1
311+let computedDelay = $t089039869._1
297312
298-let computedGenerator = $t084809446._2
313+let computedGenerator = $t089039869._2
299314
300-let computedTotalBalance = $t084809446._3
315+let computedTotalBalance = $t089039869._3
301316
302-let filteredMiners = $t084809446._4
317+let filteredMiners = $t089039869._4
303318
304319 func getChainLastBlockId (chainId) = chainMeta(chainId)._2
305320
306321
307-let $t095129619 = blockMeta(mainChainLastBlock)
322+let $t0993510042 = blockMeta(mainChainLastBlock)
308323
309-let mclbIgnored1 = $t095129619._1
324+let mclbIgnored1 = $t0993510042._1
310325
311-let mainChainEpoch = $t095129619._2
326+let mainChainEpoch = $t0993510042._2
312327
313-let mainChainParentHash = $t095129619._3
328+let mainChainParentHash = $t0993510042._3
314329
315-let mainChainGenerator = $t095129619._4
330+let mainChainGenerator = $t0993510042._4
316331
317332 func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
318333 let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
319334 let halfBalance = (computedTotalBalance / 2)
320335 func step (prev,next) = {
321- let $t0998510049 = prev
322- let thisEpoch = $t0998510049._1
323- let totalBalance = $t0998510049._2
324- let maybeSafeEpoch = $t0998510049._3
325- let prevMiners = $t0998510049._4
336+ let $t01040810472 = prev
337+ let thisEpoch = $t01040810472._1
338+ let totalBalance = $t01040810472._2
339+ let maybeSafeEpoch = $t01040810472._3
340+ let prevMiners = $t01040810472._4
326341 match maybeSafeEpoch {
327342 case _: Unit =>
328- let $t01010710273 = if ((thisEpoch == height))
343+ let $t01053010696 = if ((thisEpoch == height))
329344 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
330345 else value(epochMeta(thisEpoch))
331- let miner = $t01010710273._1
332- let prevEpoch = $t01010710273._2
333- let lastBlockHash = $t01010710273._3
334- if ((prevEpoch == 0))
346+ let miner = $t01053010696._1
347+ let prevEpoch = $t01053010696._2
348+ let lastBlockHash = $t01053010696._3
349+ if (if ((prevEpoch == 0))
350+ then true
351+ else ((height - thisEpoch) >= 100))
335352 then $Tuple4(thisEpoch, totalBalance, lastBlockHash, allMiners)
336353 else {
337- let $t01039810600 = if (containsElement(prevMiners, miner))
354+ let $t01085011052 = if (containsElement(prevMiners, miner))
338355 then $Tuple2(totalBalance, prevMiners)
339356 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
340- let newTotalBalance = $t01039810600._1
341- let newMiners = $t01039810600._2
357+ let newTotalBalance = $t01085011052._1
358+ let newMiners = $t01085011052._2
342359 if ((newTotalBalance > halfBalance))
343360 then $Tuple4(thisEpoch, newTotalBalance, lastBlockHash, allMiners)
344361 else $Tuple4(prevEpoch, newTotalBalance, unit, newMiners)
345362 }
346363 case _ =>
347364 prev
348365 }
349366 }
350367
351- let $t01083310966 = {
352- let $l = (offsets_100 ++ offsets_100)
368+ let $t01128511403 = {
369+ let $l = offsets_100
353370 let $s = size($l)
354371 let $acc0 = $Tuple4(height, 0, unit, nil)
355372 func $f0_1 ($a,$i) = if (($i >= $s))
356373 then $a
357374 else step($a, $l[$i])
358375
359376 func $f0_2 ($a,$i) = if (($i >= $s))
360377 then $a
361- else throw("List size exceeds 200")
378+ else throw("List size exceeds 100")
362379
363- $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($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 101), 102), 103), 104), 105), 106), 107), 108), 109), 110), 111), 112), 113), 114), 115), 116), 117), 118), 119), 120), 121), 122), 123), 124), 125), 126), 127), 128), 129), 130), 131), 132), 133), 134), 135), 136), 137), 138), 139), 140), 141), 142), 143), 144), 145), 146), 147), 148), 149), 150), 151), 152), 153), 154), 155), 156), 157), 158), 159), 160), 161), 162), 163), 164), 165), 166), 167), 168), 169), 170), 171), 172), 173), 174), 175), 176), 177), 178), 179), 180), 181), 182), 183), 184), 185), 186), 187), 188), 189), 190), 191), 192), 193), 194), 195), 196), 197), 198), 199), 200)
380+ $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)
364381 }
365- let fallbackEpoch = $t01083310966._1
366- let totalBalance = $t01083310966._2
367- let finalizedBlockHashOpt = $t01083310966._3
368- let miners = $t01083310966._4
382+ let fallbackEpoch = $t01128511403._1
383+ let totalBalance = $t01128511403._2
384+ let finalizedBlockHashOpt = $t01128511403._3
385+ let miners = $t01128511403._4
369386 match finalizedBlockHashOpt {
370387 case finalizedBlockHash: String =>
371388 finalizedBlockHash
372389 case _ =>
373390 value(epochMeta(fallbackEpoch))._3
374391 }
375392 }
376393
377394
378395 func supportingBalance (chainId) = {
379396 func addBalance (acc,generatorStr) = {
380- let $t01123611272 = acc
381- let totalBalance = $t01123611272._1
382- let generators = $t01123611272._2
397+ let $t01167311709 = acc
398+ let totalBalance = $t01167311709._1
399+ let generators = $t01167311709._2
383400 let generator = addressFromStringValue(generatorStr)
384401 if (containsElement(generators, generator))
385402 then acc
386403 else {
387404 let balance = generatingBalance(generator)
388405 $Tuple2((totalBalance + balance), (generators :+ generator))
389406 }
390407 }
391408
392409 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
393- let $t01159411659 = {
410+ let $t01203112096 = {
394411 let $l = allGenerators
395412 let $s = size($l)
396413 let $acc0 = $Tuple2(0, nil)
397414 func $f0_1 ($a,$i) = if (($i >= $s))
398415 then $a
399416 else addBalance($a, $l[$i])
400417
401418 func $f0_2 ($a,$i) = if (($i >= $s))
402419 then $a
403420 else throw("List size exceeds 100")
404421
405422 $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)
406423 }
407- let balance = $t01159411659._1
408- let _g = $t01159411659._2
424+ let balance = $t01203112096._1
425+ let _g = $t01203112096._2
409426 balance
410427 }
411428
412429
413430 func isContractSetup () = isDefined(getInteger(minerRewardKey))
414431
415432
416433 func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
417434 then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
418435 else unit
419436
420437
421438 func isReferenceCorrect (reference,lastBlock) = if ((reference == lastBlock))
422439 then unit
423440 else throw(((("Expected a reference to the chain last block: 0x" + lastBlock) + ". Got: 0x") + reference))
424441
425442
426443 func chainIsInactive (chainId) = {
427444 let firstBlockId = getStringValue(chainFirstBlockIdKey(chainId))
428445 let firstValidAltChainId = valueOrElse(getInteger(firstValidAltChainIdKey), 0)
429446 if ((firstValidAltChainId > chainId))
430447 then true
431448 else (blockMeta(getStringValue(finalizedBlockKey))._1 > blockMeta(firstBlockId)._1)
432449 }
433450
434451
435452 func minerChainId (miner) = valueOrElse(getInteger(minerChainIdKey(miner)), getInteger(("chainIdOf" + toString(miner))))
436453
437454
438455 func ensureExpectedOrInactiveChain (generator,expectedChainId,checkHeightBlock) = {
439456 let heightIsCorrect = match checkHeightBlock {
440457 case blockHash: String =>
441458 let lastMinedBlockHeight = lastHeightBy(generator, mainChainId)
442459 ((blockMeta(blockHash)._1 + 1) > lastMinedBlockHeight)
443460 case _ =>
444461 true
445462 }
446463 match minerChainId(generator) {
447464 case currentId: Int =>
448465 if (if ((currentId == expectedChainId))
449466 then true
450467 else if (chainIsInactive(currentId))
451468 then heightIsCorrect
452469 else false)
453470 then unit
454471 else throw(("miner is mining other chain " + toString(currentId)))
455472 case _ =>
456473 unit
457474 }
458475 }
459476
460477
461478 func ensureCorrectEpoch (epoch) = if ((epoch == height))
462479 then unit
463480 else throw(((("Expected block from epoch " + toString(height)) + ". Got ") + toString(epoch)))
464481
465482
466483 func addSupporter (chainId,generator) = {
467484 let supportersStr = getStringValue(supportersKey(chainId))
468485 let supporters = split_4C(supportersStr, SEP)
469486 if (containsElement(supporters, toString(generator)))
470487 then nil
471488 else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
472489 }
473490
474491
475492 func setOrFail (flags,index) = if ((0 > index))
476493 then throw(("Can't withdraw at negative index: " + toString(index)))
477494 else {
478495 let flagsSize = size(flags)
479496 if ((index >= flagsSize))
480497 then {
481498 let addZeroes = (index - flagsSize)
482499 if ((addZeroes > size(zeroesStr)))
483500 then throw((("Can't add " + toString(addZeroes)) + " empty flags. Contact with developers"))
484501 else ((flags + take(zeroesStr, addZeroes)) + "1")
485502 }
486503 else {
487504 let tail = drop(flags, index)
488505 let atIndex = take(tail, 1)
489506 if ((atIndex == "0"))
490507 then ((take(flags, index) + "1") + drop(tail, 1))
491508 else throw((("Transfer #" + toString(index)) + " has been already taken"))
492509 }
493510 }
494511
495512
496513 func validateBlockHash (hexStr) = {
497514 let decodedBytes = fromBase16String(hexStr)
498515 if ((size(decodedBytes) != 32))
499516 then throw("invalid block id length")
500517 else hexStr
501518 }
502519
503520
504521 func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
505522 let curFinalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
506523 let newFinalizedBlockHash = calculateFinalizedBlockHash(caller, prevEpoch, newBlockHashHex)
507524 if (if ((newFinalizedBlockHash == newBlockHashHex))
508525 then true
509526 else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockHeight))
510527 then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
511528 else nil
512529 }
513530
514531
515532 @Callable(i)
516533 func appendBlock_v3 (blockHashHex,referenceHex,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
517534 let checkCaller = if ((thisEpochMiner == i.originCaller))
518535 then true
519536 else match thisEpochMiner {
520537 case epochMiner: Address =>
521538 throw(("not allowed to forge blocks in this epoch, expected from " + toString(epochMiner)))
522539 case _ =>
523540 throw("not allowed to forge blocks in this epoch, epoch miner is absent")
524541 }
525542 if ((checkCaller == checkCaller))
526543 then {
527544 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
528- let $t01580415855 = chainMeta(chainId)
529- let chainHeight = $t01580415855._1
530- let lastBlockId = $t01580415855._2
545+ let $t01624116292 = chainMeta(chainId)
546+ let chainHeight = $t01624116292._1
547+ let lastBlockId = $t01624116292._2
531548 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
532549 if ((checkReference == checkReference))
533550 then {
534551 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, false)
535552 if ((checkTransfers == checkTransfers))
536553 then {
537554 let newChainHeight = (chainHeight + 1)
538555 let checkBlockHash = validateBlockHash(blockHashHex)
539556 if ((checkBlockHash == checkBlockHash))
540557 then [mkBlockMetaEntry(blockHashHex, newChainHeight, lastBlockId, i.originCaller, chainId, elToClTransfersRootHashHex, lastClToElTransferIndex), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), StringEntry(epochMetaKey(height), ((((toString(value(thisEpochMiner)) + SEP) + toString(thisEpochRef)) + SEP) + blockHashHex))]
541558 else throw("Strict value is not equal to itself.")
542559 }
543560 else throw("Strict value is not equal to itself.")
544561 }
545562 else throw("Strict value is not equal to itself.")
546563 }
547564 else throw("Strict value is not equal to itself.")
548565 }
549566
550567
551568
552569 @Callable(i)
553570 func extendMainChain_v3 (blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
554571 let checkBlockHash = validateBlockHash(blockHashHex)
555572 if ((checkBlockHash == checkBlockHash))
556573 then {
557574 let checkEpoch = ensureCorrectEpoch(epoch)
558575 if ((checkEpoch == checkEpoch))
559576 then {
560577 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, unit)
561578 if ((checkChain == checkChain))
562579 then {
563580 let checkReference = isReferenceCorrect(referenceHex, mainChainLastBlock)
564581 if ((checkReference == checkReference))
565582 then {
566583 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, true)
567584 if ((checkTransfers == checkTransfers))
568585 then {
569586 let thisEpochMeta = match epochMeta(height) {
570587 case _: Unit =>
571588 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(mainChainEpoch)) + SEP) + blockHashHex))
572589 case other =>
573590 throw("Epoch already started")
574591 }
575592 if ((thisEpochMeta == thisEpochMeta))
576593 then {
577594 let checkGenerator = ensureMiningEpoch(i.originCaller)
578595 if ((checkGenerator == checkGenerator))
579596 then {
580597 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, mainChainEpoch)
581598 let newChainHeight = (mainChainHeight + 1)
582599 ([mkBlockMetaEntry(blockHashHex, newChainHeight, mainChainLastBlock, i.originCaller, mainChainId, elToClTransfersRootHashHex, lastClToElTransferIndex), mkChainMetaEntry(mainChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), mainChainId), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), thisEpochMeta] ++ updateFinalizedBlock)
583600 }
584601 else throw("Strict value is not equal to itself.")
585602 }
586603 else throw("Strict value is not equal to itself.")
587604 }
588605 else throw("Strict value is not equal to itself.")
589606 }
590607 else throw("Strict value is not equal to itself.")
591608 }
592609 else throw("Strict value is not equal to itself.")
593610 }
594611 else throw("Strict value is not equal to itself.")
595612 }
596613 else throw("Strict value is not equal to itself.")
597614 }
598615
599616
600617
601618 @Callable(i)
602619 func startAltChain_v3 (blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
603620 let checkBlockHash = validateBlockHash(blockHashHex)
604621 if ((checkBlockHash == checkBlockHash))
605622 then {
606623 let checkEpoch = ensureCorrectEpoch(epoch)
607624 if ((checkEpoch == checkEpoch))
608625 then {
609- let $t01827818400 = blockMeta(referenceHex)
610- let refChainHeight = $t01827818400._1
611- let refEpoch = $t01827818400._2
612- let refRef = $t01827818400._3
613- let refGenerator = $t01827818400._4
614- let refIgnored5 = $t01827818400._5
615- let refIgnored6 = $t01827818400._6
616- let refTransferIndex = $t01827818400._7
626+ let $t01871518837 = blockMeta(referenceHex)
627+ let refChainHeight = $t01871518837._1
628+ let refEpoch = $t01871518837._2
629+ let refRef = $t01871518837._3
630+ let refGenerator = $t01871518837._4
631+ let refIgnored5 = $t01871518837._5
632+ let refIgnored6 = $t01871518837._6
633+ let refTransferIndex = $t01871518837._7
617634 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
618635 let epochRef = if ((refEpoch >= finalizedEpoch))
619636 then refEpoch
620637 else throw((((("Can not start alt chain from epoch " + toString(refEpoch)) + ", epoch ") + toString(finalizedEpoch)) + " is finalized"))
621638 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, referenceHex)
622639 if ((checkChain == checkChain))
623640 then {
624641 let checkTransfers = ensureCorrectTransfers(refTransferIndex, lastClToElTransferIndex, true)
625642 if ((checkTransfers == checkTransfers))
626643 then {
627644 let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
628645 let newChainHeight = (refChainHeight + 1)
629646 let thisEpochMeta = match epochMeta(height) {
630647 case _: Unit =>
631648 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(epochRef)) + SEP) + blockHashHex))
632649 case other =>
633650 throw("Epoch already started")
634651 }
635652 let checkGenerator = ensureMiningEpoch(i.originCaller)
636653 if ((checkGenerator == checkGenerator))
637654 then [thisEpochMeta, mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, i.originCaller, newChainId, elToClTransfersRootHashHex, lastClToElTransferIndex), 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)]
638655 else throw("Strict value is not equal to itself.")
639656 }
640657 else throw("Strict value is not equal to itself.")
641658 }
642659 else throw("Strict value is not equal to itself.")
643660 }
644661 else throw("Strict value is not equal to itself.")
645662 }
646663 else throw("Strict value is not equal to itself.")
647664 }
648665
649666
650667
651668 @Callable(i)
652669 func extendAltChain_v3 (chainId,blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
653670 let checkBlockHash = validateBlockHash(blockHashHex)
654671 if ((checkBlockHash == checkBlockHash))
655672 then {
656673 let checkEpoch = ensureCorrectEpoch(epoch)
657674 if ((checkEpoch == checkEpoch))
658675 then {
659676 let chainFirstBlockMeta = blockMeta(getStringValue(chainFirstBlockIdKey(chainId)))
660677 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
661678 if ((checkChain == checkChain))
662679 then {
663- let $t02074420798 = chainMeta(chainId)
664- let chainHeight = $t02074420798._1
665- let chainLastBlock = $t02074420798._2
680+ let $t02118121235 = chainMeta(chainId)
681+ let chainHeight = $t02118121235._1
682+ let chainLastBlock = $t02118121235._2
666683 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
667684 if ((checkReference == checkReference))
668685 then {
669686 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, true)
670687 if ((checkTransfers == checkTransfers))
671688 then {
672689 let newChainHeight = (chainHeight + 1)
673690 let prevEpoch = blockMeta(referenceHex)._2
674691 let updateMainChainData = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
675692 then {
676693 let lastChainId = valueOrElse(getInteger(lastChainIdKey), 0)
677694 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, prevEpoch)
678695 ([IntegerEntry(chainForkedHeightKey(mainChainId), chainFirstBlockMeta._1), IntegerEntry(mainChainIdKey, chainId), IntegerEntry(firstValidAltChainIdKey, (lastChainId + 1))] ++ updateFinalizedBlock)
679696 }
680697 else nil
681698 let thisEpochMeta = match epochMeta(height) {
682699 case _: Unit =>
683700 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(prevEpoch)) + SEP) + blockHashHex))
684701 case other =>
685702 throw("Epoch already started")
686703 }
687704 if ((thisEpochMeta == thisEpochMeta))
688705 then {
689706 let checkGenerator = ensureMiningEpoch(i.originCaller)
690707 if ((checkGenerator == checkGenerator))
691708 then {
692709 let updateMainChainLastMinedBlock = if (if ((updateMainChainData == nil))
693710 then (valueOrElse(minerChainId(i.originCaller), 0) != chainId)
694711 else false)
695712 then [IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), chainFirstBlockMeta._1)]
696713 else nil
697714 ((([mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, i.originCaller, chainId, elToClTransfersRootHashHex, lastClToElTransferIndex), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), thisEpochMeta, IntegerEntry(minerChainIdKey(i.originCaller), chainId), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight)] ++ updateMainChainData) ++ addSupporter(chainId, i.originCaller)) ++ updateMainChainLastMinedBlock)
698715 }
699716 else throw("Strict value is not equal to itself.")
700717 }
701718 else throw("Strict value is not equal to itself.")
702719 }
703720 else throw("Strict value is not equal to itself.")
704721 }
705722 else throw("Strict value is not equal to itself.")
706723 }
707724 else throw("Strict value is not equal to itself.")
708725 }
709726 else throw("Strict value is not equal to itself.")
710727 }
711728 else throw("Strict value is not equal to itself.")
712729 }
713730
714731
715732
716733 @Callable(i)
717734 func join (rewardAddress) = {
718735 func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
719736 case pk: ByteVector =>
720737 if ((pk == i.originCallerPublicKey))
721738 then unit
722739 else throw(((("EL miner address " + elAddressHex) + " is already linked with ") + toBase58String(pk)))
723740 case _ =>
724741 unit
725742 }
726743
727744 if (!(isContractSetup()))
728745 then throw("The contract has not yet set up")
729746 else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
730747 then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
731748 else if ((size(rewardAddress) != 20))
732749 then throw("rewardAddress should be an L2 address")
733750 else if ((size(allMiners) >= 50))
734751 then throw("too many miners")
735752 else {
736753 func checkExistence (exists,miner) = if (exists)
737754 then true
738755 else (miner == toString(i.originCaller))
739756
740757 let alreadyExists = {
741758 let $l = allMiners
742759 let $s = size($l)
743760 let $acc0 = false
744761 func $f0_1 ($a,$i) = if (($i >= $s))
745762 then $a
746763 else checkExistence($a, $l[$i])
747764
748765 func $f0_2 ($a,$i) = if (($i >= $s))
749766 then $a
750767 else throw("List size exceeds 50")
751768
752769 $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)
753770 }
754771 if (alreadyExists)
755772 then nil
756773 else {
757774 let newMiner = toString(i.originCaller)
758775 let rewardAddressHex = toBase16String(rewardAddress)
759776 let check = ensureNotOverrideOtherMinerPk(rewardAddressHex)
760777 if ((check == check))
761778 then {
762779 let newMiners = if ((size(allMiners) == 0))
763780 then newMiner
764781 else ((allMinersStr + SEP) + newMiner)
765782 let deleteOldRewardAddressPk = match getString(minerRewardAddressKey(newMiner)) {
766783 case oldAddress: String =>
767784 if ((oldAddress == toBase16String(rewardAddress)))
768785 then nil
769786 else [DeleteEntry(minerPkKey(oldAddress))]
770787 case _ =>
771788 nil
772789 }
773790 ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + rewardAddressHex)), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ deleteOldRewardAddressPk)
774791 }
775792 else throw("Strict value is not equal to itself.")
776793 }
777794 }
778795 }
779796
780797
781798
782799 @Callable(i)
783800 func leave () = {
784801 let leavingMiner = toString(i.originCaller)
785802 func skipLeavingMiner (acc,miner) = if ((miner == leavingMiner))
786803 then acc
787804 else (acc :+ miner)
788805
789806 let remainingMiners = {
790807 let $l = allMiners
791808 let $s = size($l)
792809 let $acc0 = nil
793810 func $f0_1 ($a,$i) = if (($i >= $s))
794811 then $a
795812 else skipLeavingMiner($a, $l[$i])
796813
797814 func $f0_2 ($a,$i) = if (($i >= $s))
798815 then $a
799816 else throw("List size exceeds 50")
800817
801818 $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)
802819 }
803820 let rewardAddrKey = minerRewardAddressKey(leavingMiner)
804821 let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
805- if ((thisEpochMiner == i.originCaller))
806- then throw("designated miner can't leave")
807- else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
822+ if ((prevRewardAddress == prevRewardAddress))
823+ then if ((thisEpochMiner == i.originCaller))
824+ then throw("designated miner can't leave")
825+ else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
826+ else throw("Strict value is not equal to itself.")
808827 }
809828
810829
811830
812831 @Callable(i)
813832 func transfer (destElAddressHex) = {
814- let checkPayment = if ((size(i.payments) == 1))
815- then true
816- else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
817- if ((checkPayment == checkPayment))
833+ let checkAddress = if ((size(destElAddressHex) == ETH_ADDRESS_STR_SIZE))
834+ then fromBase16String(destElAddressHex)
835+ else throw(((("Address should have " + toString(ETH_ADDRESS_STR_SIZE)) + " characters, got ") + toString(size(destElAddressHex))))
836+ if ((checkAddress == checkAddress))
818837 then {
819- let checkDestAddress = if ((size(fromBase16String(destElAddressHex)) == 20))
838+ let checkPayment = if ((size(i.payments) == 1))
820839 then true
821- else throw("Destination address must be a valid ethereum address")
822- if ((checkDestAddress == checkDestAddress))
840+ else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
841+ if ((checkPayment == checkPayment))
823842 then {
824843 let tokenIdStr = getStringValue(tokenIdKey)
825844 let tokenId = fromBase58String(tokenIdStr)
826845 let t = i.payments[0]
827846 let checkAssetId = match t.assetId {
828847 case assetId: ByteVector =>
829848 if ((assetId == tokenId))
830849 then true
831850 else throw(((("Expected " + tokenIdStr) + " in the payment, got ") + toBase58String(assetId)))
832851 case _ =>
833852 throw((("Expected " + tokenIdStr) + " in the payment, got Waves"))
834853 }
835854 if ((checkAssetId == checkAssetId))
836855 then {
837856 let lastIndex = blockMeta(mainChainLastBlock)._7
838- let queueSize = ((nativeTransfersCount - lastIndex) + 1)
857+ let queueSize = (nativeTransfersCount - lastIndex)
839858 let checkQueueLimit = if ((160 > queueSize))
840859 then amountGtEq(t, 1000000, queueSize)
841860 else if ((1600 > queueSize))
842861 then amountGtEq(t, 10000000, queueSize)
843862 else if ((3200 > queueSize))
844863 then amountGtEq(t, 100000000, queueSize)
845864 else if ((6400 > queueSize))
846865 then amountGtEq(t, 1000000000, queueSize)
847866 else throw((("Transfers denied for queue size of " + toString(queueSize)) + ". Wait until current transfers processed"))
848867 if ((checkQueueLimit == checkQueueLimit))
849868 then [IntegerEntry(nativeTransfersCountKey, (nativeTransfersCount + 1)), mkNativeTransferEntry(nativeTransfersCount, destElAddressHex, t.amount), Burn(tokenId, t.amount)]
850869 else throw("Strict value is not equal to itself.")
851870 }
852871 else throw("Strict value is not equal to itself.")
853872 }
854873 else throw("Strict value is not equal to itself.")
855874 }
856875 else throw("Strict value is not equal to itself.")
857876 }
858877
859878
860879
861880 @Callable(i)
862881 func withdraw (blockHashHex,merkleProof,transferIndexInBlock,amount) = {
863882 let withdrawBlockMeta = blockMeta(blockHashHex)
864883 let withdrawBlockHeight = withdrawBlockMeta._1
865884 let finalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
866885 let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
867886 if ((withdrawBlockHeight > finalizedBlockHeight))
868887 then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
869- else {
870- let withdrawBlockChainId = withdrawBlockMeta._5
871- let isMainChain = (withdrawBlockChainId == mainChainId)
872- let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
873- case forkedHeight: Int =>
874- (forkedHeight > withdrawBlockHeight)
875- case _ =>
876- throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
877- }
878- if (if (isMainChain)
879- then true
880- else relatesToMainChain)
881- then {
882- let recipient = i.originCaller
883- let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
884- let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
885- let amountBytes = toBytes(amount)
886- let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
887- let elEventDataDigest = blake2b256_16Kb(elEventData)
888- let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
889- let expectedRootHash = withdrawBlockMeta._6
890- if ((calculatedRootHash == expectedRootHash))
891- then {
892- let tokenId = fromBase58String(getStringValue(tokenIdKey))
893- let transfersKey = blockElToClTransfersKey(blockHashHex)
888+ else if ((size(merkleProof) != WITHDRAW_PROOFS_SIZE))
889+ then throw(((("Expected " + toString(WITHDRAW_PROOFS_SIZE)) + " proofs, got ") + toString(size(merkleProof))))
890+ else if ((0 > transferIndexInBlock))
891+ then throw(("Transfer index in block should be nonnegative, got " + toString(transferIndexInBlock)))
892+ else if ((0 >= amount))
893+ then throw(("Amount should be positive, got " + toString(amount)))
894+ else {
895+ let withdrawBlockChainId = withdrawBlockMeta._5
896+ let isMainChain = (withdrawBlockChainId == mainChainId)
897+ let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
898+ case forkedHeight: Int =>
899+ (forkedHeight > withdrawBlockHeight)
900+ case _ =>
901+ throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
902+ }
903+ if (if (isMainChain)
904+ then true
905+ else relatesToMainChain)
906+ then {
907+ let recipient = i.originCaller
908+ let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
909+ let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
910+ let amountBytes = toBytes(amount)
911+ let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
912+ let elEventDataDigest = blake2b256_16Kb(elEventData)
913+ let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
914+ let expectedRootHash = withdrawBlockMeta._6
915+ if ((calculatedRootHash == expectedRootHash))
916+ then {
917+ let tokenId = fromBase58String(getStringValue(tokenIdKey))
918+ let transfersKey = blockElToClTransfersKey(blockHashHex)
894919 [Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
895- }
896- else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
897- }
898- else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
899- }
920+ }
921+ else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
922+ }
923+ else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
924+ }
900925 }
901926
902927
903928
904929 @Callable(i)
905930 func setup (genesisBlockHashHex,minerRewardInGwei,stakingContractAddressB58,elBridgeAddressHex) = if (isContractSetup())
906931 then throw("The contract has been already set up")
907932 else if ((0 > minerRewardInGwei))
908933 then throw("The miner reward must be nonnegative")
909934 else {
910935 let genesisBlockHash = fromBase16String(genesisBlockHashHex)
911- let emptyPk = base58'11111111111111111111111111111111'
912- let genesisMinerAddress = addressFromPublicKey(emptyPk)
913- let genesisEthRewardAddress = base58'11111111111111111111'
914- let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
915- let issue = Issue("UNIT0", "Native token", 0, 8, true)
916- let tokenId = calculateAssetId(issue)
917- let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, height, genesisBlockReferenceHash, genesisMinerAddress, 0, toBase16String(base58''), -1)
936+ let checkGenesisBlockHashSize = if ((size(genesisBlockHash) == BLOCK_HASH_SIZE))
937+ then true
938+ else throw("Wrong genesis block hash")
939+ if ((checkGenesisBlockHashSize == checkGenesisBlockHashSize))
940+ then {
941+ let stakingContractAddressBytes = fromBase58String(stakingContractAddressB58)
942+ let checkStakingContractAddress = if ((size(stakingContractAddressBytes) == ADDRESS_SIZE))
943+ then true
944+ else throw("Wrong staking contract address")
945+ if ((checkStakingContractAddress == checkStakingContractAddress))
946+ then {
947+ let checkElBridgeAddress = if ((size(elBridgeAddressHex) == ETH_ADDRESS_STR_SIZE))
948+ then fromBase16String(elBridgeAddressHex)
949+ else throw("Wrong bridge address")
950+ if ((checkElBridgeAddress == checkElBridgeAddress))
951+ then {
952+ let emptyPk = base58'11111111111111111111111111111111'
953+ let genesisMinerAddress = addressFromPublicKey(emptyPk)
954+ let genesisEthRewardAddress = base58'11111111111111111111'
955+ let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
956+ let issue = Issue("UNIT0", "Native token", 0, 8, true)
957+ let tokenId = calculateAssetId(issue)
958+ let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, genesisMinerAddress, 0, toBase16String(base58''), -1)
918959 [genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(stakingContractAddressKey, stakingContractAddressB58), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, ("0x" + elBridgeAddressHex))]
960+ }
961+ else throw("Strict value is not equal to itself.")
962+ }
963+ else throw("Strict value is not equal to itself.")
964+ }
965+ else throw("Strict value is not equal to itself.")
919966 }
920967
921968

github/deemru/w8io/169f3d6 
172.99 ms