2024.04.03 17:55 [3046754] smart account 3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch > SELF 0.00000000 Waves

{ "type": 13, "id": "EuXdBSC64ERnDjXwNWTLZ8E4i7NvL3ZhBhtv2he8MwkJ", "fee": 2300000, "feeAssetId": null, "timestamp": 1712159695000, "version": 1, "sender": "3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch", "senderPublicKey": "3xjN6fjYDXBGUE1mcRw2Fvr4R6tEZnuJA98QFGF99sXd", "proofs": [ "3fDFa24maL6s818qSCgMujs9AWEvFvkZurscVpnUMtnnNWAegCsrtpMtaPbd3apBRvX7sXcU9GW6eDeqMrwVkiu6" ], "script": "base64:CAIlCAISBAoCAgISBQoDAgIBEgUKAwICARIGCgQBAgIBEgMKAQISADIAB0lOVF9NQVgA//////////9/AAVXQVZFUwCAwtcvAAtNSU5fQkFMQU5DRQkAaAIAoJwBBQVXQVZFUwATTUFYX0JMT0NLU19BVF9FUE9DSAAyAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgAAxBRERSRVNTX1NJWkUAGgATTUFYX0JMT0NLU19TVFJfU0laRQkAZAIJAGgCAEAFE01BWF9CTE9DS1NfQVRfRVBPQ0gJAGUCBRNNQVhfQkxPQ0tTX0FUX0VQT0NIAAEAEHRoaXNFcG9jaERhdGFLZXkCDXRoaXNFcG9jaERhdGEADGFsbE1pbmVyc0tleQIJYWxsTWluZXJzAA5tYWluQ2hhaW5JZEtleQILbWFpbkNoYWluSWQADmxhc3RDaGFpbklkS2V5AgtsYXN0Q2hhaW5JZAAYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AhVsYXN0RXBvY2hCbG9ja3NOdW1iZXIADm1pbmVyUmV3YXJkS2V5AgttaW5lclJld2FyZAAWc3Rha2luZ0NvbnRyYWN0QWRkcmVzcwkBB0FkZHJlc3MBCQERQGV4dHJOYXRpdmUoMTA1MikCBQR0aGlzAhZzdGFraW5nQ29udHJhY3RBZGRyZXNzARFnZW5lcmF0aW5nQmFsYW5jZQEHYWRkcmVzcwQHJG1hdGNoMAkAnQgCBRZzdGFraW5nQ29udHJhY3RBZGRyZXNzCQCsAgICBCVzX18JAKUIAQUHYWRkcmVzcwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3N0cgUHJG1hdGNoMAQJcGFyYW1MaXN0CQC1CQIFA3N0cgICX18ECnByZXZIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAQQLcHJldkJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAgQKbmV4dEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAADBAtuZXh0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAAEAwkAZwIFBmhlaWdodAUKbmV4dEhlaWdodAULbmV4dEJhbGFuY2UDCQBnAgUGaGVpZ2h0BQpwcmV2SGVpZ2h0BQtwcmV2QmFsYW5jZQAAAAABDGJsb2NrTWV0YUtleQEHYmxvY2tJZAkArAICAglibG9ja01ldGEJANwEAQUHYmxvY2tJZAEKY2hhaW5JZEtleQEJZ2VuZXJhdG9yCQCsAgICCWNoYWluSWRPZgkA3AQBBQlnZW5lcmF0b3IBDmNoYWluSGVpZ2h0S2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIGSGVpZ2h0ARRjaGFpbkZpcnN0QmxvY2tJZEtleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCCkZpcnN0QmxvY2sBE2NoYWluTGFzdEJsb2NrSWRLZXkBB2NoYWluSWQJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAglMYXN0QmxvY2sBE2NoYWluQWxsQmxvY2tJZHNLZXkCB2NoYWluSWQBbgkArAICCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIJQWxsQmxvY2tzCQCkAwEFAW4BGGNoYWluQWxsQmxvY2tJZHNMYXN0TktleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCDkFsbEJsb2Nrc0xhc3ROAQ1zdXBwb3J0ZXJzS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKU3VwcG9ydGVycwESbWluZXJSZXdhcmRBZGRyZXNzAQltaW5lckFkZHIJAKwCAgkArAICAgVtaW5lcgUJbWluZXJBZGRyAg1SZXdhcmRBZGRyZXNzARJtaW5lckpvaW5IZWlnaHRLZXkBCW1pbmVyQWRkcgkArAICCQCsAgICBW1pbmVyBQltaW5lckFkZHICCkpvaW5IZWlnaHQBCm1pbmVyUGtLZXkBDXJld2FyZEFkZHJlc3MJAKwCAgkArAICAgVtaW5lcgUNcmV3YXJkQWRkcmVzcwICUEsBEGxlYXZpbmdNaW5lcnNLZXkBBWVwb2NoCQCsAgICD2xlYXZpbmdNaW5lcnNBdAkApAMBBQVlcG9jaAALbWFpbkNoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObWFpbkNoYWluSWRLZXkAAAAOdGhpc0Vwb2NoTWluZXIEByRtYXRjaDAJAKIIAQUQdGhpc0Vwb2NoRGF0YUtleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEEHJhd1RoaXNFcG9jaERhdGEFByRtYXRjaDAEDXRoaXNFcG9jaERhdGEJALUJAgUQcmF3VGhpc0Vwb2NoRGF0YQUDU0VQBAl0aGlzRXBvY2gJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ10aGlzRXBvY2hEYXRhAAADCQAAAgUJdGhpc0Vwb2NoBQZoZWlnaHQJANkEAQkAkQMCBQ10aGlzRXBvY2hEYXRhAAEFBHVuaXQFBHVuaXQACWFsbE1pbmVycwQHJG1hdGNoMAkAoggBBQxhbGxNaW5lcnNLZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBANyYXcFByRtYXRjaDAJALwJAgUDcmF3BQNTRVAFA25pbAAQYWxsTGVhdmluZ01pbmVycwQHJG1hdGNoMAkAoggBCQEQbGVhdmluZ01pbmVyc0tleQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3JhdwUHJG1hdGNoMAkAvAkCBQNyYXcFA1NFUAUDbmlsAQlibG9ja01ldGEBB2Jsb2NrSWQEBG1ldGEJARFAZXh0ck5hdGl2ZSgxMDU3KQEJAQxibG9ja01ldGFLZXkBBQdibG9ja0lkBBFtZXRhV2l0aG91dEhlaWdodAkAygECBQRtZXRhAAgEFm1ldGFXaXRob3V0SGVpZ2h0RXBvY2gJAMoBAgURbWV0YVdpdGhvdXRIZWlnaHQACAQLYmxvY2tIZWlnaHQJALEJAQkAyQECBQRtZXRhAAgECmJsb2NrRXBvY2gJALEJAQkAyQECBRFtZXRhV2l0aG91dEhlaWdodAAIBAtibG9ja1BhcmVudAkAyQECBRZtZXRhV2l0aG91dEhlaWdodEVwb2NoBQ9CTE9DS19IQVNIX1NJWkUEDmJsb2NrR2VuZXJhdG9yCQDMAQIFBG1ldGEFDEFERFJFU1NfU0laRQkAlgoEBQtibG9ja0hlaWdodAUKYmxvY2tFcG9jaAULYmxvY2tQYXJlbnQFDmJsb2NrR2VuZXJhdG9yAQxzZXRFcG9jaERhdGEBCWdlbmVyYXRvcgkBC1N0cmluZ0VudHJ5AgUQdGhpc0Vwb2NoRGF0YUtleQkArAICCQCsAgIJAKQDAQUGaGVpZ2h0BQNTRVAJANgEAQgFCWdlbmVyYXRvcgVieXRlcwALJHQwMzY1MzQ3MTAECWhpdFNvdXJjZQQHJG1hdGNoMAgFCWxhc3RCbG9jawN2cmYDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQDdnJmBQckbWF0Y2gwBQN2cmYIBQlsYXN0QmxvY2sTZ2VuZXJhdGlvblNpZ25hdHVyZQoBDHByb2Nlc3NNaW5lcgIEcHJldgVtaW5lcgQLJHQwMzk1MTQwMTQFBHByZXYECXByZXZEZWxheQgFCyR0MDM5NTE0MDE0Al8xBAlwcmV2TWluZXIIBQskdDAzOTUxNDAxNAJfMgQQcHJldlRvdGFsQmFsYW5jZQgFCyR0MDM5NTE0MDE0Al8zBApwcmV2TWluZXJzCAULJHQwMzk1MTQwMTQCXzQEDG1pbmVyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUFbWluZXIED3dhdmVzR2VuQmFsYW5jZQgJAO8HAQUMbWluZXJBZGRyZXNzCmdlbmVyYXRpbmcEDG1pbmVyQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUMbWluZXJBZGRyZXNzAwMDCQBmAgULTUlOX0JBTEFOQ0UFD3dhdmVzR2VuQmFsYW5jZQYJAGcCAAAFDG1pbmVyQmFsYW5jZQYJAGYCCQELdmFsdWVPckVsc2UCCQCfCAEJARJtaW5lckpvaW5IZWlnaHRLZXkBBQVtaW5lcgUHSU5UX01BWAUGaGVpZ2h0BQRwcmV2BAluZXh0RGVsYXkJAIUHAgUMbWluZXJBZGRyZXNzBQxtaW5lckJhbGFuY2UDCQBmAgUJcHJldkRlbGF5BQluZXh0RGVsYXkJAJYKBAUJbmV4dERlbGF5BQVtaW5lcgkAZAIFEHByZXZUb3RhbEJhbGFuY2UFDG1pbmVyQmFsYW5jZQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgkAlgoEBQlwcmV2RGVsYXkFCXByZXZNaW5lcgkAZAIFEHByZXZUb3RhbEJhbGFuY2UFDG1pbmVyQmFsYW5jZQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgoAAiRsCQDOCAIFCWFsbE1pbmVycwUQYWxsTGVhdmluZ01pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAUHSU5UX01BWAIAAAAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMcHJvY2Vzc01pbmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIADWNvbXB1dGVkRGVsYXkIBQskdDAzNjUzNDcxMAJfMQARY29tcHV0ZWRHZW5lcmF0b3IIBQskdDAzNjUzNDcxMAJfMgAUY29tcHV0ZWRUb3RhbEJhbGFuY2UIBQskdDAzNjUzNDcxMAJfMwAOZmlsdGVyZWRNaW5lcnMIBQskdDAzNjUzNDcxMAJfNAASc2FmZVJvbGxiYWNrSGVpZ2h0CgEKYWRkQmFsYW5jZQIDYWNjCmJsb2NrSWRTdHIECyR0MDQ4MjQ0ODY4BQNhY2MEDHRvdGFsQmFsYW5jZQgFCyR0MDQ4MjQ0ODY4Al8xBAZwcmV2SWQIBQskdDA0ODI0NDg2OAJfMgQKZ2VuZXJhdG9ycwgFCyR0MDQ4MjQ0ODY4Al8zAwkAZgIFDHRvdGFsQmFsYW5jZQkAaQIFFGNvbXB1dGVkVG90YWxCYWxhbmNlAAIFA2FjYwQHYmxvY2tJZAkA3QQBBQpibG9ja0lkU3RyBAlnZW5lcmF0b3IJAQdBZGRyZXNzAQgJAQlibG9ja01ldGEBBQdibG9ja0lkAl80AwkBD2NvbnRhaW5zRWxlbWVudAIFCmdlbmVyYXRvcnMFCWdlbmVyYXRvcgUDYWNjBAdiYWxhbmNlCQERZ2VuZXJhdGluZ0JhbGFuY2UBBQlnZW5lcmF0b3IJAJUKAwkAZAIFDHRvdGFsQmFsYW5jZQUHYmFsYW5jZQUHYmxvY2tJZAkAzQgCBQpnZW5lcmF0b3JzBQlnZW5lcmF0b3IKAQtnZXRCbG9ja0lkcwEBbgQGcmF3U3RyCQELdmFsdWVPckVsc2UCCQCiCAEJARNjaGFpbkFsbEJsb2NrSWRzS2V5AgULbWFpbkNoYWluSWQFAW4CAAMJAAACBQZyYXdTdHICAAUDbmlsCQC8CQIFBnJhd1N0cgUDU0VQBAVsYXN0TgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQULbWFpbkNoYWluSWQAAAQMYWxsQmxvY2tzSWRzCQDOCAIJAM4IAgkAzggCCQELZ2V0QmxvY2tJZHMBBQVsYXN0TgkBC2dldEJsb2NrSWRzAQkAZQIFBWxhc3ROAAEJAQtnZXRCbG9ja0lkcwEJAGUCBQVsYXN0TgACCQELZ2V0QmxvY2tJZHMBCQBlAgUFbGFzdE4AAwQLJHQwNTYzNjU3MTAKAAIkbAUMYWxsQmxvY2tzSWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDAAABAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQphZGRCYWxhbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhVMaXN0IHNpemUgZXhjZWVkcyAyMDAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBf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ZWN0b3IEAmxiBQckbWF0Y2gwAwkAAAIFCXJlZmVyZW5jZQUCbGIFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICAi5FeHBlY3RlZCBhIHJlZmVyZW5jZSB0byB0aGUgY2hhaW4gbGFzdCBibG9jazogCQDcBAEFAmxiAgcuIEdvdDogCQDcBAEFCXJlZmVyZW5jZQkAAgECC01hdGNoIGVycm9yAQ9jaGFpbklzSW5hY3RpdmUBB2NoYWluSWQEDGZpcnN0QmxvY2tJZAkBEUBleHRyTmF0aXZlKDEwNTcpAQkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAkAZgIFEnNhZmVSb2xsYmFja0hlaWdodAgJAQlibG9ja01ldGEBBQxmaXJzdEJsb2NrSWQCXzEBGWVuc3VyZU1haW5PckluYWN0aXZlQ2hhaW4BCWdlbmVyYXRvcgQHJG1hdGNoMAkAnwgBCQEKY2hhaW5JZEtleQEIBQlnZW5lcmF0b3IFYnl0ZXMDCQABAgUHJG1hdGNoMAIDSW50BAljdXJyZW50SWQFByRtYXRjaDADAwkAAAIFCWN1cnJlbnRJZAULbWFpbkNoYWluSWQGCQEPY2hhaW5Jc0luYWN0aXZlAQUJY3VycmVudElkBQR1bml0CQACAQkArAICAhxtaW5lciBpcyBtaW5pbmcgb3RoZXIgY2hhaW4gCQCkAwEFCWN1cnJlbnRJZAUEdW5pdAEXZW5zdXJlQWx0Q2hhaW5FeHRlbnNpb24CCWdlbmVyYXRvcgdjaGFpbklkBAckbWF0Y2gwCQCfCAEJAQpjaGFpbklkS2V5AQgFCWdlbmVyYXRvcgVieXRlcwMJAAECBQckbWF0Y2gwAgNJbnQECWN1cnJlbnRJZAUHJG1hdGNoMAMJAAACBQljdXJyZW50SWQFB2NoYWluSWQFBHVuaXQEFWV4dGVuZGluZ0ZpcnN0QmxvY2tJZAkBEUBleHRyTmF0aXZlKDEwNTcpAQkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAQYbWluZXJDdXJyZW50Rmlyc3RCbG9ja0lkCQERQGV4dHJOYXRpdmUoMTA1NykBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQljdXJyZW50SWQEGWV4dGVuZGluZ0ZpcnN0QmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQUVZXh0ZW5kaW5nRmlyc3RCbG9ja0lkAl8xBBxtaW5lckN1cnJlbnRGaXJzdEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEFGG1pbmVyQ3VycmVudEZpcnN0QmxvY2tJZAJfMQMJAGYCBRlleHRlbmRpbmdGaXJzdEJsb2NrSGVpZ2h0BRxtaW5lckN1cnJlbnRGaXJzdEJsb2NrSGVpZ2h0BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICHG1pbmVyIGlzIG1pbmluZyBvdGhlciBjaGFpbiAJAKQDAQUJY3VycmVudElkAiYsIGhlaWdodCBvZiB0aGUgYWx0IGNoYWluIGZpcnN0IGJsb2NrIAkApAMBBRlleHRlbmRpbmdGaXJzdEJsb2NrSGVpZ2h0Aj8gaXMgbm90IGxlc3MgdGhhbiBoZWlnaHQgb2YgdGhlIG1pbmVyIGFjdGl2ZSBjaGFpbiBmaXJzdCBibG9jayAJAKQDAQUcbWluZXJDdXJyZW50Rmlyc3RCbG9ja0hlaWdodAUEdW5pdAEgZW5zdXJlUmVmZXJlbmNlSXNTYWZlRm9yUm9sbGJhY2sBCXJlZmVyZW5jZQQLc3RhcnRIZWlnaHQICQEJYmxvY2tNZXRhAQUJcmVmZXJlbmNlAl8xAwkAZgIFEnNhZmVSb2xsYmFja0hlaWdodAULc3RhcnRIZWlnaHQJAAIBCQCsAgIJAKwCAgkArAICAg1zdGFydCBoZWlnaHQgCQCkAwEFC3N0YXJ0SGVpZ2h0Ah0gaXMgbGVzcyB0aGFuIG1pbmltdW0gaGVpZ2h0IAkApAMBBRJzYWZlUm9sbGJhY2tIZWlnaHQFBHVuaXQBEmVuc3VyZUNvcnJlY3RFcG9jaAEFZXBvY2gDCQAAAgUFZXBvY2gFBmhlaWdodAUEdW5pdAkAAgEJAKwCAgkArAICCQCsAgICGkV4cGVjdGVkIGJsb2NrIGZyb20gZXBvY2ggCQCkAwEFBmhlaWdodAIGLiBHb3QgCQCkAwEFBWVwb2NoARFjaGVja0Jsb2Nrc051bWJlcgADCQBmAgUTTUFYX0JMT0NLU19BVF9FUE9DSAkBEUBleHRyTmF0aXZlKDEwNTUpAQUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5BQR1bml0CQACAQIiTWF4IGJsb2NrcyBudW1iZXIgYXQgZXBvY2ggcmVhY2hlZAEMYWRkU3VwcG9ydGVyAgdjaGFpbklkCWdlbmVyYXRvcgQNc3VwcG9ydGVyc1N0cgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDXN1cHBvcnRlcnNLZXkBBQdjaGFpbklkBApzdXBwb3J0ZXJzCQC1CQIFDXN1cHBvcnRlcnNTdHIFA1NFUAMJAQ9jb250YWluc0VsZW1lbnQCBQpzdXBwb3J0ZXJzCQClCAEFCWdlbmVyYXRvcgUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAkArAICCQCsAgIFDXN1cHBvcnRlcnNTdHIFA1NFUAkApQgBBQlnZW5lcmF0b3IFA25pbAYBaQELYXBwZW5kQmxvY2sCCWJsb2NrSGFzaAlyZWZlcmVuY2UEBWNoZWNrCQERY2hlY2tCbG9ja3NOdW1iZXIAAwkAAAIFBWNoZWNrBQVjaGVjawMJAQIhPQIFDnRoaXNFcG9jaE1pbmVyCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzBAckbWF0Y2gwBQ50aGlzRXBvY2hNaW5lcgMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAplcG9jaE1pbmVyBQckbWF0Y2gwCQACAQkArAICAjlub3QgYWxsb3dlZCB0byBmb3JnZSBibG9ja3MgaW4gdGhpcyBlcG9jaCwgZXhwZWN0ZWQgZnJvbSAJANgEAQUKZXBvY2hNaW5lcgkAAgECQG5vdCBhbGxvd2VkIHRvIGZvcmdlIGJsb2NrcyBpbiB0aGlzIGVwb2NoLCBlcG9jaCBtaW5lciBpcyBhYnNlbnQEB2NoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBCmNoYWluSWRLZXkBCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzBQttYWluQ2hhaW5JZAQLbGFzdEJsb2NrSWQJARFAZXh0ck5hdGl2ZSgxMDU3KQEJARNjaGFpbkxhc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAQGY2hlY2syCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUJcmVmZXJlbmNlBQtsYXN0QmxvY2tJZAMJAAACBQZjaGVjazIFBmNoZWNrMgQLY2hhaW5IZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDmNoYWluSGVpZ2h0S2V5AQUHY2hhaW5JZAAABAluZXdIZWlnaHQJAGQCBQtjaGFpbkhlaWdodAABBAxibG9ja3NOdW1iZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AAAEDG5ld0Jsb2NrTWV0YQkAywECCQDLAQIJAMsBAgkAmgMBBQluZXdIZWlnaHQJAJoDAQUGaGVpZ2h0BQtsYXN0QmxvY2tJZAgIBQFpDG9yaWdpbkNhbGxlcgVieXRlcwkAzAgCCQELQmluYXJ5RW50cnkCCQEMYmxvY2tNZXRhS2V5AQUJYmxvY2tIYXNoBQxuZXdCbG9ja01ldGEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5jaGFpbkhlaWdodEtleQEFB2NoYWluSWQFCW5ld0hlaWdodAkAzAgCCQELQmluYXJ5RW50cnkCCQETY2hhaW5MYXN0QmxvY2tJZEtleQEFB2NoYWluSWQFCWJsb2NrSGFzaAkAzAgCCQEMSW50ZWdlckVudHJ5AgUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5CQBkAgUMYmxvY2tzTnVtYmVyAAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ9leHRlbmRNYWluQ2hhaW4DCWJsb2NrSGFzaAlyZWZlcmVuY2UFZXBvY2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQKY2hlY2tDaGFpbgkBGWVuc3VyZU1haW5PckluYWN0aXZlQ2hhaW4BCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQLY2hhaW5IZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDmNoYWluSGVpZ2h0S2V5AQULbWFpbkNoYWluSWQAAAQQbGFzdFZhbGlkQmxvY2tJZAkAoQgBCQETY2hhaW5MYXN0QmxvY2tJZEtleQEFC21haW5DaGFpbklkBA5jaGVja1JlZmVyZW5jZQkBEmlzUmVmZXJlbmNlQ29ycmVjdAIFCXJlZmVyZW5jZQUQbGFzdFZhbGlkQmxvY2tJZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDWJsb2NrSWRzTGFzdE4JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBGGNoYWluQWxsQmxvY2tJZHNMYXN0TktleQEFC21haW5DaGFpbklkAAAECGJsb2NrSWRzCQELdmFsdWVPckVsc2UCCQCiCAEJARNjaGFpbkFsbEJsb2NrSWRzS2V5AgULbWFpbkNoYWluSWQFDWJsb2NrSWRzTGFzdE4CAAQJbmV3SGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQRdXBkYXRlQWxsQmxvY2tJZHMDCQBnAgkAsQIBBQhibG9ja0lkcwUTTUFYX0JMT0NLU19TVFJfU0laRQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBGGNoYWluQWxsQmxvY2tJZHNMYXN0TktleQEFC21haW5DaGFpbklkCQBkAgUNYmxvY2tJZHNMYXN0TgABCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNjaGFpbkFsbEJsb2NrSWRzS2V5AgULbWFpbkNoYWluSWQJAGQCBQ1ibG9ja0lkc0xhc3ROAAEJANwEAQUJYmxvY2tIYXNoBQNuaWwEC25ld0Jsb2NrSWRzAwkAAAIFCGJsb2NrSWRzAgAJANwEAQUJYmxvY2tIYXNoCQCsAgIJAKwCAgkA3AQBBQlibG9ja0hhc2gFA1NFUAUIYmxvY2tJZHMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQttYWluQ2hhaW5JZAUNYmxvY2tJZHNMYXN0TgULbmV3QmxvY2tJZHMFA25pbAQMZmlyc3RCbG9ja0lkBAckbWF0Y2gwBRBsYXN0VmFsaWRCbG9ja0lkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAmlkBQckbWF0Y2gwBQNuaWwJAMwIAgkBC0JpbmFyeUVudHJ5AgkBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQULbWFpbkNoYWluSWQFCWJsb2NrSGFzaAUDbmlsBAxuZXdCbG9ja01ldGEJAMsBAgkAywECCQDLAQIJAJoDAQUJbmV3SGVpZ2h0CQCaAwEFBmhlaWdodAUJcmVmZXJlbmNlCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDOCAIJAM4IAgkAzAgCCQELQmluYXJ5RW50cnkCCQEMYmxvY2tNZXRhS2V5AQUJYmxvY2tIYXNoBQxuZXdCbG9ja01ldGEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5jaGFpbkhlaWdodEtleQEFC21haW5DaGFpbklkBQluZXdIZWlnaHQJAMwIAgkBC0JpbmFyeUVudHJ5AgkBE2NoYWluTGFzdEJsb2NrSWRLZXkBBQttYWluQ2hhaW5JZAUJYmxvY2tIYXNoCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEKY2hhaW5JZEtleQEICAUBaQxvcmlnaW5DYWxsZXIFYnl0ZXMFC21haW5DaGFpbklkCQDMCAIJAQxzZXRFcG9jaERhdGEBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIFGGxhc3RFcG9jaEJsb2Nrc051bWJlcktleQABBQNuaWwFDGZpcnN0QmxvY2tJZAURdXBkYXRlQWxsQmxvY2tJZHMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENc3RhcnRBbHRDaGFpbgMJYmxvY2tIYXNoCXJlZmVyZW5jZQVlcG9jaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFBWVwb2NoAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gEDmNoZWNrUmVmZXJlbmNlCQEgZW5zdXJlUmVmZXJlbmNlSXNTYWZlRm9yUm9sbGJhY2sBBQlyZWZlcmVuY2UDCQAAAgUOY2hlY2tSZWZlcmVuY2UFDmNoZWNrUmVmZXJlbmNlBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQKY2hlY2tDaGFpbgkBGWVuc3VyZU1haW5PckluYWN0aXZlQ2hhaW4BCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQKbmV3Q2hhaW5JZAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObGFzdENoYWluSWRLZXkAAAABBAluZXdIZWlnaHQJAGQCCAkBCWJsb2NrTWV0YQEFCXJlZmVyZW5jZQJfMQABBAxuZXdCbG9ja01ldGEJAMsBAgkAywECCQDLAQIJAJoDAQUJbmV3SGVpZ2h0CQCaAwEFBmhlaWdodAUJcmVmZXJlbmNlCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQxibG9ja01ldGFLZXkBBQlibG9ja0hhc2gFDG5ld0Jsb2NrTWV0YQkAzAgCCQELQmluYXJ5RW50cnkCCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQpuZXdDaGFpbklkBQlibG9ja0hhc2gJAMwIAgkBC0JpbmFyeUVudHJ5AgkBE2NoYWluTGFzdEJsb2NrSWRLZXkBBQpuZXdDaGFpbklkBQlibG9ja0hhc2gJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQpuZXdDaGFpbklkAAAJANwEAQUJYmxvY2tIYXNoCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOY2hhaW5IZWlnaHRLZXkBBQpuZXdDaGFpbklkBQluZXdIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQpjaGFpbklkS2V5AQgIBQFpDG9yaWdpbkNhbGxlcgVieXRlcwUKbmV3Q2hhaW5JZAkAzAgCCQEMc2V0RXBvY2hEYXRhAQgFAWkMb3JpZ2luQ2FsbGVyCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1zdXBwb3J0ZXJzS2V5AQUKbmV3Q2hhaW5JZAkApQgBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIFGGxhc3RFcG9jaEJsb2Nrc051bWJlcktleQABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5sYXN0Q2hhaW5JZEtleQUKbmV3Q2hhaW5JZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmV4dGVuZEFsdENoYWluBAdjaGFpbklkCWJsb2NrSGFzaAlyZWZlcmVuY2UFZXBvY2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQKY2hlY2tDaGFpbgkBF2Vuc3VyZUFsdENoYWluRXh0ZW5zaW9uAggFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkAwkAAAIFCmNoZWNrQ2hhaW4FCmNoZWNrQ2hhaW4EDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUJcmVmZXJlbmNlCQChCAEJARNjaGFpbkxhc3RCbG9ja0lkS2V5AQUHY2hhaW5JZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEC2NoYWluSGVpZ2h0CQELdmFsdWVPckVsc2UCCQCfCAEJAQ5jaGFpbkhlaWdodEtleQEFB2NoYWluSWQAAAQNYmxvY2tJZHNMYXN0TgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQUHY2hhaW5JZAAABAhibG9ja0lkcwkBEUBleHRyTmF0aXZlKDEwNTgpAQkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQdjaGFpbklkBQ1ibG9ja0lkc0xhc3ROBAluZXdIZWlnaHQJAGQCBQtjaGFpbkhlaWdodAABBBF1cGRhdGVBbGxCbG9ja0lkcwMJAGcCCQCxAgEFCGJsb2NrSWRzBRNNQVhfQkxPQ0tTX1NUUl9TSVpFCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEYY2hhaW5BbGxCbG9ja0lkc0xhc3ROS2V5AQUHY2hhaW5JZAkAZAIFDWJsb2NrSWRzTGFzdE4AAQkAzAgCCQELU3RyaW5nRW50cnkCCQETY2hhaW5BbGxCbG9ja0lkc0tleQIFB2NoYWluSWQJAGQCBQ1ibG9ja0lkc0xhc3ROAAEJANwEAQUJYmxvY2tIYXNoBQNuaWwEC25ld0Jsb2NrSWRzCQCsAgIJAKwCAgkA3AQBBQlibG9ja0hhc2gFA1NFUAUIYmxvY2tJZHMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2NoYWluQWxsQmxvY2tJZHNLZXkCBQdjaGFpbklkBQ1ibG9ja0lkc0xhc3ROBQtuZXdCbG9ja0lkcwUDbmlsBA5tYWluQ2hhaW5FbnRyeQMJAGYCCQERc3VwcG9ydGluZ0JhbGFuY2UBBQdjaGFpbklkCQBpAgUUY29tcHV0ZWRUb3RhbEJhbGFuY2UAAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObWFpbkNoYWluSWRLZXkFB2NoYWluSWQFA25pbAUDbmlsBAxuZXdCbG9ja01ldGEJAMsBAgkAywECCQDLAQIJAJoDAQUJbmV3SGVpZ2h0CQCaAwEFBmhlaWdodAUJcmVmZXJlbmNlCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQDOCAIJAM4IAgkAzggCCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQxibG9ja01ldGFLZXkBBQlibG9ja0hhc2gFDG5ld0Jsb2NrTWV0YQkAzAgCCQELQmluYXJ5RW50cnkCCQETY2hhaW5MYXN0QmxvY2tJZEtleQEFB2NoYWluSWQFCWJsb2NrSGFzaAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmNoYWluSGVpZ2h0S2V5AQUHY2hhaW5JZAUJbmV3SGVpZ2h0CQDMCAIJAQxzZXRFcG9jaERhdGEBCAUBaQxvcmlnaW5DYWxsZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQpjaGFpbklkS2V5AQgIBQFpDG9yaWdpbkNhbGxlcgVieXRlcwUHY2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUYbGFzdEVwb2NoQmxvY2tzTnVtYmVyS2V5AAEFA25pbAUObWFpbkNoYWluRW50cnkJAQxhZGRTdXBwb3J0ZXICBQdjaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFEXVwZGF0ZUFsbEJsb2NrSWRzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBGpvaW4BDXJld2FyZEFkZHJlc3MKARJjaGVja1Jld2FyZEFkZHJlc3MBB2FkZHJlc3MEByRtYXRjaDAJAKEIAQkBCm1pbmVyUGtLZXkBBQdhZGRyZXNzAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIFAnBrCAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICAhFMMiBtaW5lciBhZGRyZXNzIAUHYWRkcmVzcwIYIGlzIGFscmVhZHkgbGlua2VkIHdpdGggCQDYBAEFAnBrBQR1bml0AwkAZgIFC01JTl9CQUxBTkNFCAkA7wcBCAUBaQxvcmlnaW5DYWxsZXIKZ2VuZXJhdGluZwkAAgEJAKwCAgkArAICCQCsAgICIUluc3VmZmljaWVudCBnZW5lcmF0aW5nIGJhbGFuY2U6IAkApAMBCAkA7wcBCAUBaQxvcmlnaW5DYWxsZXIKZ2VuZXJhdGluZwIMLiBSZXF1aXJlZDogCQCkAwEFC01JTl9CQUxBTkNFAwkBAiE9AgkAyAEBBQ1yZXdhcmRBZGRyZXNzABQJAAIBAiVyZXdhcmRBZGRyZXNzIHNob3VsZCBiZSBhbiBMMiBhZGRyZXNz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AQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyBBBuZXdMZWF2aW5nTWluZXJzCAUNJHQwMTcwMTExNzEwMQJfMQQJaXNVcGRhdGVkCAUNJHQwMTcwMTExNzEwMQJfMgQWbmV3TGVhdmluZ01pbmVyc0FjdGlvbgMJAQIhPQIFEG5ld0xlYXZpbmdNaW5lcnMFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQEQbGVhdmluZ01pbmVyc0tleQEFBmhlaWdodAkAugkCBRBuZXdMZWF2aW5nTWluZXJzBQNTRVAFA25pbAMJAQIhPQIFEGFsbExlYXZpbmdNaW5lcnMFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBCQEQbGVhdmluZ01pbmVyc0tleQEFBmhlaWdodAUDbmlsBQNuaWwECmpvaW5IZWlnaHQDBQlpc1VwZGF0ZWQFBmhlaWdodAkAZAIFBmhlaWdodAABBBhkZWxldGVPbGRSZXdhcmRBZGRyZXNzUGsEByRtYXRjaDAJAKEIAQkBEm1pbmVyUmV3YXJkQWRkcmVzcwEFCG5ld01pbmVyAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IECm9sZEFkZHJlc3MFByRtYXRjaDADCQAAAgUKb2xkQWRkcmVzcwUNcmV3YXJkQWRkcmVzcwUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQptaW5lclBrS2V5AQkA3AQBBQpvbGRBZGRyZXNzBQNuaWwFA25pbAkAzggCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5BQluZXdNaW5lcnMJAMwIAgkBDEludGVnZXJFbnRyeQIJARJtaW5lckpvaW5IZWlnaHRLZXkBBQhuZXdNaW5lcgUKam9pbkhlaWdodAkAzAgCCQELQmluYXJ5RW50cnkCCQESbWluZXJSZXdhcmRBZGRyZXNzAQUIbmV3TWluZXIFDXJld2FyZEFkZHJlc3MJAMwIAgkBC0JpbmFyeUVudHJ5AgkBCm1pbmVyUGtLZXkBBRByZXdhcmRBZGRyZXNzSGV4CAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFA25pbAUWbmV3TGVhdmluZ01pbmVyc0FjdGlvbgUYZGVsZXRlT2xkUmV3YXJkQWRkcmVzc1BrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBWxlYXZlAAQMbGVhdmluZ01pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgoBC2ZpbHRlck1pbmVyAgNhY2MFbWluZXIDCQAAAgUFbWluZXIFDGxlYXZpbmdNaW5lcgUDYWNjCQDNCAIFA2FjYwUFbWluZXIECnJlc3RNaW5lcnMKAAIkbAUJYWxsTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQtmaWx0ZXJNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAwkAAAIFDnRoaXNFcG9jaE1pbmVyCAgFAWkMb3JpZ2luQ2FsbGVyBWJ5dGVzCQACAQIcZGVzaWduYXRlZCBtaW5lciBjYW4ndCBsZWF2ZQQHJG1hdGNoMAkAnwgBCQESbWluZXJKb2luSGVpZ2h0S2V5AQUMbGVhdmluZ01pbmVyAwkAAQIFByRtYXRjaDACA0ludAQLbWluZXJIZWlnaHQFByRtYXRjaDADCQBmAgULbWluZXJIZWlnaHQFBmhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCBQxhbGxNaW5lcnNLZXkJALoJAgUKcmVzdE1pbmVycwUDU0VQCQDMCAIJAQtEZWxldGVFbnRyeQEJARJtaW5lckpvaW5IZWlnaHRLZXkBBQxsZWF2aW5nTWluZXIFA25pbAQQb2xkTGVhdmluZ01pbmVycwkBC3ZhbHVlT3JFbHNlAgkAoggBCQEQbGVhdmluZ01pbmVyc0tleQEFBmhlaWdodAIABBBuZXdMZWF2aW5nTWluZXJzAwkAAAIFEG9sZExlYXZpbmdNaW5lcnMCAAUMbGVhdmluZ01pbmVyCQCsAgIJAKwCAgUQb2xkTGVhdmluZ01pbmVycwUDU0VQBQxsZWF2aW5nTWluZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5CQC6CQIFCnJlc3RNaW5lcnMFA1NFUAkAzAgCCQELRGVsZXRlRW50cnkBCQESbWluZXJKb2luSGVpZ2h0S2V5AQUMbGVhdmluZ01pbmVyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBsZWF2aW5nTWluZXJzS2V5AQUGaGVpZ2h0BRBuZXdMZWF2aW5nTWluZXJzBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5CQC6CQIFCnJlc3RNaW5lcnMFA1NFUAUDbmlsAHiFeYA=", "chainId": 84, "height": 3046754, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 8 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let INT_MAX = 9223372036854775807
5+
6+let WAVES = 100000000
7+
8+let MIN_BALANCE = (20000 * WAVES)
9+
10+let MAX_BLOCKS_AT_EPOCH = 50
11+
12+let SEP = ","
13+
14+let BLOCK_HASH_SIZE = 32
15+
16+let ADDRESS_SIZE = 26
17+
18+let MAX_BLOCKS_STR_SIZE = ((64 * MAX_BLOCKS_AT_EPOCH) + (MAX_BLOCKS_AT_EPOCH - 1))
19+
20+let thisEpochDataKey = "thisEpochData"
21+
22+let allMinersKey = "allMiners"
23+
24+let mainChainIdKey = "mainChainId"
25+
26+let lastChainIdKey = "lastChainId"
27+
28+let lastEpochBlocksNumberKey = "lastEpochBlocksNumber"
29+
30+let minerRewardKey = "minerReward"
31+
32+let stakingContractAddress = Address(getBinaryValue(this, "stakingContractAddress"))
33+
34+func generatingBalance (address) = match getString(stakingContractAddress, ("%s__" + toString(address))) {
35+ case str: String =>
36+ let paramList = split(str, "__")
37+ let prevHeight = parseIntValue(paramList[1])
38+ let prevBalance = parseIntValue(paramList[2])
39+ let nextHeight = parseIntValue(paramList[3])
40+ let nextBalance = parseIntValue(paramList[4])
41+ if ((height >= nextHeight))
42+ then nextBalance
43+ else if ((height >= prevHeight))
44+ then prevBalance
45+ else 0
46+ case _ =>
47+ 0
48+}
49+
50+
51+func blockMetaKey (blockId) = ("blockMeta" + toBase16String(blockId))
52+
53+
54+func chainIdKey (generator) = ("chainIdOf" + toBase16String(generator))
55+
56+
57+func chainHeightKey (chainId) = (("chain" + toString(chainId)) + "Height")
58+
59+
60+func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
61+
62+
63+func chainLastBlockIdKey (chainId) = (("chain" + toString(chainId)) + "LastBlock")
64+
65+
66+func chainAllBlockIdsKey (chainId,n) = ((("chain" + toString(chainId)) + "AllBlocks") + toString(n))
67+
68+
69+func chainAllBlockIdsLastNKey (chainId) = (("chain" + toString(chainId)) + "AllBlocksLastN")
70+
71+
72+func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
73+
74+
75+func minerRewardAddress (minerAddr) = (("miner" + minerAddr) + "RewardAddress")
76+
77+
78+func minerJoinHeightKey (minerAddr) = (("miner" + minerAddr) + "JoinHeight")
79+
80+
81+func minerPkKey (rewardAddress) = (("miner" + rewardAddress) + "PK")
82+
83+
84+func leavingMinersKey (epoch) = ("leavingMinersAt" + toString(epoch))
85+
86+
87+let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
88+
89+let thisEpochMiner = match getString(thisEpochDataKey) {
90+ case rawThisEpochData: String =>
91+ let thisEpochData = split(rawThisEpochData, SEP)
92+ let thisEpoch = parseIntValue(thisEpochData[0])
93+ if ((thisEpoch == height))
94+ then fromBase58String(thisEpochData[1])
95+ else unit
96+ case _ =>
97+ unit
98+}
99+
100+let allMiners = match getString(allMinersKey) {
101+ case raw: String =>
102+ split_4C(raw, SEP)
103+ case _ =>
104+ nil
105+}
106+
107+let allLeavingMiners = match getString(leavingMinersKey(height)) {
108+ case raw: String =>
109+ split_4C(raw, SEP)
110+ case _ =>
111+ nil
112+}
113+
114+func blockMeta (blockId) = {
115+ let meta = getBinaryValue(blockMetaKey(blockId))
116+ let metaWithoutHeight = drop(meta, 8)
117+ let metaWithoutHeightEpoch = drop(metaWithoutHeight, 8)
118+ let blockHeight = toInt(take(meta, 8))
119+ let blockEpoch = toInt(take(metaWithoutHeight, 8))
120+ let blockParent = take(metaWithoutHeightEpoch, BLOCK_HASH_SIZE)
121+ let blockGenerator = takeRight(meta, ADDRESS_SIZE)
122+ $Tuple4(blockHeight, blockEpoch, blockParent, blockGenerator)
123+ }
124+
125+
126+func setEpochData (generator) = StringEntry(thisEpochDataKey, ((toString(height) + SEP) + toBase58String(generator.bytes)))
127+
128+
129+let $t036534710 = {
130+ let hitSource = match lastBlock.vrf {
131+ case vrf: ByteVector =>
132+ vrf
133+ case _ =>
134+ lastBlock.generationSignature
135+ }
136+ func processMiner (prev,miner) = {
137+ let $t039514014 = prev
138+ let prevDelay = $t039514014._1
139+ let prevMiner = $t039514014._2
140+ let prevTotalBalance = $t039514014._3
141+ let prevMiners = $t039514014._4
142+ let minerAddress = addressFromStringValue(miner)
143+ let wavesGenBalance = wavesBalance(minerAddress).generating
144+ let minerBalance = generatingBalance(minerAddress)
145+ if (if (if ((MIN_BALANCE > wavesGenBalance))
146+ then true
147+ else (0 >= minerBalance))
148+ then true
149+ else (valueOrElse(getInteger(minerJoinHeightKey(miner)), INT_MAX) > height))
150+ then prev
151+ else {
152+ let nextDelay = calculateDelay(minerAddress, minerBalance)
153+ if ((prevDelay > nextDelay))
154+ then $Tuple4(nextDelay, miner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
155+ else $Tuple4(prevDelay, prevMiner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
156+ }
157+ }
158+
159+ let $l = (allMiners ++ allLeavingMiners)
160+ let $s = size($l)
161+ let $acc0 = $Tuple4(INT_MAX, "", 0, nil)
162+ func $f0_1 ($a,$i) = if (($i >= $s))
163+ then $a
164+ else processMiner($a, $l[$i])
165+
166+ func $f0_2 ($a,$i) = if (($i >= $s))
167+ then $a
168+ else throw("List size exceeds 50")
169+
170+ $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)
171+ }
172+
173+let computedDelay = $t036534710._1
174+
175+let computedGenerator = $t036534710._2
176+
177+let computedTotalBalance = $t036534710._3
178+
179+let filteredMiners = $t036534710._4
180+
181+let safeRollbackHeight = {
182+ func addBalance (acc,blockIdStr) = {
183+ let $t048244868 = acc
184+ let totalBalance = $t048244868._1
185+ let prevId = $t048244868._2
186+ let generators = $t048244868._3
187+ if ((totalBalance > (computedTotalBalance / 2)))
188+ then acc
189+ else {
190+ let blockId = fromBase16String(blockIdStr)
191+ let generator = Address(blockMeta(blockId)._4)
192+ if (containsElement(generators, generator))
193+ then acc
194+ else {
195+ let balance = generatingBalance(generator)
196+ $Tuple3((totalBalance + balance), blockId, (generators :+ generator))
197+ }
198+ }
199+ }
200+
201+ func getBlockIds (n) = {
202+ let rawStr = valueOrElse(getString(chainAllBlockIdsKey(mainChainId, n)), "")
203+ if ((rawStr == ""))
204+ then nil
205+ else split_4C(rawStr, SEP)
206+ }
207+
208+ let lastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(mainChainId)), 0)
209+ let allBlocksIds = (((getBlockIds(lastN) ++ getBlockIds((lastN - 1))) ++ getBlockIds((lastN - 2))) ++ getBlockIds((lastN - 3)))
210+ let $t056365710 = {
211+ let $l = allBlocksIds
212+ let $s = size($l)
213+ let $acc0 = $Tuple3(0, base58'', nil)
214+ func $f0_1 ($a,$i) = if (($i >= $s))
215+ then $a
216+ else addBalance($a, $l[$i])
217+
218+ func $f0_2 ($a,$i) = if (($i >= $s))
219+ then $a
220+ else throw("List size exceeds 200")
221+
222+ $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)
223+ }
224+ let _b = $t056365710._1
225+ let blockId = $t056365710._2
226+ blockMeta(blockId)._1
227+ }
228+
229+func supportingBalance (chainId) = {
230+ func addBalance (acc,generatorStr) = {
231+ let $t058555891 = acc
232+ let totalBalance = $t058555891._1
233+ let generators = $t058555891._2
234+ let generator = addressFromStringValue(generatorStr)
235+ if (containsElement(generators, generator))
236+ then acc
237+ else {
238+ let balance = generatingBalance(generator)
239+ $Tuple2((totalBalance + balance), (generators :+ generator))
240+ }
241+ }
242+
243+ let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
244+ let $t062136278 = {
245+ let $l = allGenerators
246+ let $s = size($l)
247+ let $acc0 = $Tuple2(0, nil)
248+ func $f0_1 ($a,$i) = if (($i >= $s))
249+ then $a
250+ else addBalance($a, $l[$i])
251+
252+ func $f0_2 ($a,$i) = if (($i >= $s))
253+ then $a
254+ else throw("List size exceeds 100")
255+
256+ $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)
257+ }
258+ let balance = $t062136278._1
259+ let _g = $t062136278._2
260+ balance
261+ }
262+
263+
264+func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
265+ then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
266+ else unit
267+
268+
269+func isReferenceCorrect (reference,lastBlock) = match lastBlock {
270+ case _: Unit =>
271+ unit
272+ case lb: ByteVector =>
273+ if ((reference == lb))
274+ then unit
275+ else throw(((("Expected a reference to the chain last block: " + toBase16String(lb)) + ". Got: ") + toBase16String(reference)))
276+ case _ =>
277+ throw("Match error")
278+}
279+
280+
281+func chainIsInactive (chainId) = {
282+ let firstBlockId = getBinaryValue(chainFirstBlockIdKey(chainId))
283+ (safeRollbackHeight > blockMeta(firstBlockId)._1)
284+ }
285+
286+
287+func ensureMainOrInactiveChain (generator) = match getInteger(chainIdKey(generator.bytes)) {
288+ case currentId: Int =>
289+ if (if ((currentId == mainChainId))
290+ then true
291+ else chainIsInactive(currentId))
292+ then unit
293+ else throw(("miner is mining other chain " + toString(currentId)))
294+ case _ =>
295+ unit
296+}
297+
298+
299+func ensureAltChainExtension (generator,chainId) = match getInteger(chainIdKey(generator.bytes)) {
300+ case currentId: Int =>
301+ if ((currentId == chainId))
302+ then unit
303+ else {
304+ let extendingFirstBlockId = getBinaryValue(chainFirstBlockIdKey(chainId))
305+ let minerCurrentFirstBlockId = getBinaryValue(chainFirstBlockIdKey(currentId))
306+ let extendingFirstBlockHeight = blockMeta(extendingFirstBlockId)._1
307+ let minerCurrentFirstBlockHeight = blockMeta(minerCurrentFirstBlockId)._1
308+ if ((extendingFirstBlockHeight > minerCurrentFirstBlockHeight))
309+ then unit
310+ else throw(((((("miner is mining other chain " + toString(currentId)) + ", height of the alt chain first block ") + toString(extendingFirstBlockHeight)) + " is not less than height of the miner active chain first block ") + toString(minerCurrentFirstBlockHeight)))
311+ }
312+ case _ =>
313+ unit
314+}
315+
316+
317+func ensureReferenceIsSafeForRollback (reference) = {
318+ let startHeight = blockMeta(reference)._1
319+ if ((safeRollbackHeight > startHeight))
320+ then throw(((("start height " + toString(startHeight)) + " is less than minimum height ") + toString(safeRollbackHeight)))
321+ else unit
322+ }
323+
324+
325+func ensureCorrectEpoch (epoch) = if ((epoch == height))
326+ then unit
327+ else throw(((("Expected block from epoch " + toString(height)) + ". Got ") + toString(epoch)))
328+
329+
330+func checkBlocksNumber () = if ((MAX_BLOCKS_AT_EPOCH > getIntegerValue(lastEpochBlocksNumberKey)))
331+ then unit
332+ else throw("Max blocks number at epoch reached")
333+
334+
335+func addSupporter (chainId,generator) = {
336+ let supportersStr = getStringValue(supportersKey(chainId))
337+ let supporters = split(supportersStr, SEP)
338+ if (containsElement(supporters, toString(generator)))
339+ then nil
340+ else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
341+ }
342+
343+
344+@Callable(i)
345+func appendBlock (blockHash,reference) = {
346+ let check = checkBlocksNumber()
347+ if ((check == check))
348+ then if ((thisEpochMiner != i.originCaller.bytes))
349+ then match thisEpochMiner {
350+ case epochMiner: ByteVector =>
351+ throw(("not allowed to forge blocks in this epoch, expected from " + toBase58String(epochMiner)))
352+ case _ =>
353+ throw("not allowed to forge blocks in this epoch, epoch miner is absent")
354+ }
355+ else {
356+ let chainId = valueOrElse(getInteger(chainIdKey(i.originCaller.bytes)), mainChainId)
357+ let lastBlockId = getBinaryValue(chainLastBlockIdKey(chainId))
358+ let check2 = isReferenceCorrect(reference, lastBlockId)
359+ if ((check2 == check2))
360+ then {
361+ let chainHeight = valueOrElse(getInteger(chainHeightKey(chainId)), 0)
362+ let newHeight = (chainHeight + 1)
363+ let blocksNumber = valueOrElse(getInteger(lastEpochBlocksNumberKey), 0)
364+ let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + lastBlockId) + i.originCaller.bytes)
365+[BinaryEntry(blockMetaKey(blockHash), newBlockMeta), IntegerEntry(chainHeightKey(chainId), newHeight), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(lastEpochBlocksNumberKey, (blocksNumber + 1))]
366+ }
367+ else throw("Strict value is not equal to itself.")
368+ }
369+ else throw("Strict value is not equal to itself.")
370+ }
371+
372+
373+
374+@Callable(i)
375+func extendMainChain (blockHash,reference,epoch) = {
376+ let checkEpoch = ensureCorrectEpoch(epoch)
377+ if ((checkEpoch == checkEpoch))
378+ then {
379+ let checkGenerator = ensureMiningEpoch(i.originCaller)
380+ if ((checkGenerator == checkGenerator))
381+ then {
382+ let checkChain = ensureMainOrInactiveChain(i.originCaller)
383+ if ((checkChain == checkChain))
384+ then {
385+ let chainHeight = valueOrElse(getInteger(chainHeightKey(mainChainId)), 0)
386+ let lastValidBlockId = getBinary(chainLastBlockIdKey(mainChainId))
387+ let checkReference = isReferenceCorrect(reference, lastValidBlockId)
388+ if ((checkReference == checkReference))
389+ then {
390+ let blockIdsLastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(mainChainId)), 0)
391+ let blockIds = valueOrElse(getString(chainAllBlockIdsKey(mainChainId, blockIdsLastN)), "")
392+ let newHeight = (chainHeight + 1)
393+ let updateAllBlockIds = if ((size(blockIds) >= MAX_BLOCKS_STR_SIZE))
394+ then [IntegerEntry(chainAllBlockIdsLastNKey(mainChainId), (blockIdsLastN + 1)), StringEntry(chainAllBlockIdsKey(mainChainId, (blockIdsLastN + 1)), toBase16String(blockHash))]
395+ else {
396+ let newBlockIds = if ((blockIds == ""))
397+ then toBase16String(blockHash)
398+ else ((toBase16String(blockHash) + SEP) + blockIds)
399+[StringEntry(chainAllBlockIdsKey(mainChainId, blockIdsLastN), newBlockIds)]
400+ }
401+ let firstBlockId = match lastValidBlockId {
402+ case id: ByteVector =>
403+ nil
404+ case _ =>
405+[BinaryEntry(chainFirstBlockIdKey(mainChainId), blockHash)]
406+ }
407+ let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes)
408+ (([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), IntegerEntry(chainHeightKey(mainChainId), newHeight), BinaryEntry(chainLastBlockIdKey(mainChainId), blockHash), IntegerEntry(chainIdKey(i.originCaller.bytes), mainChainId), setEpochData(i.originCaller), IntegerEntry(lastEpochBlocksNumberKey, 1)] ++ firstBlockId) ++ updateAllBlockIds)
409+ }
410+ else throw("Strict value is not equal to itself.")
411+ }
412+ else throw("Strict value is not equal to itself.")
413+ }
414+ else throw("Strict value is not equal to itself.")
415+ }
416+ else throw("Strict value is not equal to itself.")
417+ }
418+
419+
420+
421+@Callable(i)
422+func startAltChain (blockHash,reference,epoch) = {
423+ let checkEpoch = ensureCorrectEpoch(epoch)
424+ if ((checkEpoch == checkEpoch))
425+ then {
426+ let checkReference = ensureReferenceIsSafeForRollback(reference)
427+ if ((checkReference == checkReference))
428+ then {
429+ let checkGenerator = ensureMiningEpoch(i.originCaller)
430+ if ((checkGenerator == checkGenerator))
431+ then {
432+ let checkChain = ensureMainOrInactiveChain(i.originCaller)
433+ if ((checkChain == checkChain))
434+ then {
435+ let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
436+ let newHeight = (blockMeta(reference)._1 + 1)
437+ let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes)
438+[BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry(chainFirstBlockIdKey(newChainId), blockHash), BinaryEntry(chainLastBlockIdKey(newChainId), blockHash), StringEntry(chainAllBlockIdsKey(newChainId, 0), toBase16String(blockHash)), IntegerEntry(chainHeightKey(newChainId), newHeight), IntegerEntry(chainIdKey(i.originCaller.bytes), newChainId), setEpochData(i.originCaller), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastEpochBlocksNumberKey, 1), IntegerEntry(lastChainIdKey, newChainId)]
439+ }
440+ else throw("Strict value is not equal to itself.")
441+ }
442+ else throw("Strict value is not equal to itself.")
443+ }
444+ else throw("Strict value is not equal to itself.")
445+ }
446+ else throw("Strict value is not equal to itself.")
447+ }
448+
449+
450+
451+@Callable(i)
452+func extendAltChain (chainId,blockHash,reference,epoch) = {
453+ let checkEpoch = ensureCorrectEpoch(epoch)
454+ if ((checkEpoch == checkEpoch))
455+ then {
456+ let checkGenerator = ensureMiningEpoch(i.originCaller)
457+ if ((checkGenerator == checkGenerator))
458+ then {
459+ let checkChain = ensureAltChainExtension(i.originCaller, chainId)
460+ if ((checkChain == checkChain))
461+ then {
462+ let checkReference = isReferenceCorrect(reference, getBinary(chainLastBlockIdKey(chainId)))
463+ if ((checkReference == checkReference))
464+ then {
465+ let chainHeight = valueOrElse(getInteger(chainHeightKey(chainId)), 0)
466+ let blockIdsLastN = valueOrElse(getInteger(chainAllBlockIdsLastNKey(chainId)), 0)
467+ let blockIds = getStringValue(chainAllBlockIdsKey(chainId, blockIdsLastN))
468+ let newHeight = (chainHeight + 1)
469+ let updateAllBlockIds = if ((size(blockIds) >= MAX_BLOCKS_STR_SIZE))
470+ then [IntegerEntry(chainAllBlockIdsLastNKey(chainId), (blockIdsLastN + 1)), StringEntry(chainAllBlockIdsKey(chainId, (blockIdsLastN + 1)), toBase16String(blockHash))]
471+ else {
472+ let newBlockIds = ((toBase16String(blockHash) + SEP) + blockIds)
473+[StringEntry(chainAllBlockIdsKey(chainId, blockIdsLastN), newBlockIds)]
474+ }
475+ let mainChainEntry = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
476+ then [IntegerEntry(mainChainIdKey, chainId)]
477+ else nil
478+ let newBlockMeta = (((toBytes(newHeight) + toBytes(height)) + reference) + i.originCaller.bytes)
479+ ((([BinaryEntry(blockMetaKey(blockHash), newBlockMeta), BinaryEntry(chainLastBlockIdKey(chainId), blockHash), IntegerEntry(chainHeightKey(chainId), newHeight), setEpochData(i.originCaller), IntegerEntry(chainIdKey(i.originCaller.bytes), chainId), IntegerEntry(lastEpochBlocksNumberKey, 1)] ++ mainChainEntry) ++ addSupporter(chainId, i.originCaller)) ++ updateAllBlockIds)
480+ }
481+ else throw("Strict value is not equal to itself.")
482+ }
483+ else throw("Strict value is not equal to itself.")
484+ }
485+ else throw("Strict value is not equal to itself.")
486+ }
487+ else throw("Strict value is not equal to itself.")
488+ }
489+
490+
491+
492+@Callable(i)
493+func join (rewardAddress) = {
494+ func checkRewardAddress (address) = match getBinary(minerPkKey(address)) {
495+ case pk: ByteVector =>
496+ if ((pk == i.originCallerPublicKey))
497+ then unit
498+ else throw(((("L2 miner address " + address) + " is already linked with ") + toBase58String(pk)))
499+ case _ =>
500+ unit
501+ }
502+
503+ if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
504+ then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
505+ else if ((size(rewardAddress) != 20))
506+ then throw("rewardAddress should be an L2 address")
507+ else {
508+ func checkExistence (exists,miner) = if (exists)
509+ then true
510+ else (miner == toString(i.originCaller))
511+
512+ let alreadyExists = {
513+ let $l = allMiners
514+ let $s = size($l)
515+ let $acc0 = false
516+ func $f0_1 ($a,$i) = if (($i >= $s))
517+ then $a
518+ else checkExistence($a, $l[$i])
519+
520+ func $f0_2 ($a,$i) = if (($i >= $s))
521+ then $a
522+ else throw("List size exceeds 50")
523+
524+ $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)
525+ }
526+ if (alreadyExists)
527+ then nil
528+ else {
529+ let newMiner = toString(i.originCaller)
530+ let rewardAddressHex = toBase16String(rewardAddress)
531+ let check = checkRewardAddress(rewardAddressHex)
532+ if ((check == check))
533+ then {
534+ func filterLeaving (acc,miner) = {
535+ let $t01671516747 = acc
536+ let accMiners = $t01671516747._1
537+ let isUpdated = $t01671516747._2
538+ if ((miner == newMiner))
539+ then $Tuple2(accMiners, true)
540+ else $Tuple2((accMiners :+ miner), isUpdated)
541+ }
542+
543+ let newMiners = if ((size(allMiners) == 0))
544+ then newMiner
545+ else ((makeString_2C(allMiners, SEP) + SEP) + newMiner)
546+ let $t01701117101 = {
547+ let $l = allLeavingMiners
548+ let $s = size($l)
549+ let $acc0 = $Tuple2(nil, false)
550+ func $f1_1 ($a,$i) = if (($i >= $s))
551+ then $a
552+ else filterLeaving($a, $l[$i])
553+
554+ func $f1_2 ($a,$i) = if (($i >= $s))
555+ then $a
556+ else throw("List size exceeds 50")
557+
558+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_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)
559+ }
560+ let newLeavingMiners = $t01701117101._1
561+ let isUpdated = $t01701117101._2
562+ let newLeavingMinersAction = if ((newLeavingMiners != nil))
563+ then [StringEntry(leavingMinersKey(height), makeString_2C(newLeavingMiners, SEP))]
564+ else if ((allLeavingMiners != nil))
565+ then [DeleteEntry(leavingMinersKey(height))]
566+ else nil
567+ let joinHeight = if (isUpdated)
568+ then height
569+ else (height + 1)
570+ let deleteOldRewardAddressPk = match getBinary(minerRewardAddress(newMiner)) {
571+ case oldAddress: ByteVector =>
572+ if ((oldAddress == rewardAddress))
573+ then nil
574+ else [DeleteEntry(minerPkKey(toBase16String(oldAddress)))]
575+ case _ =>
576+ nil
577+ }
578+ (([StringEntry(allMinersKey, newMiners), IntegerEntry(minerJoinHeightKey(newMiner), joinHeight), BinaryEntry(minerRewardAddress(newMiner), rewardAddress), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ newLeavingMinersAction) ++ deleteOldRewardAddressPk)
579+ }
580+ else throw("Strict value is not equal to itself.")
581+ }
582+ }
583+ }
584+
585+
586+
587+@Callable(i)
588+func leave () = {
589+ let leavingMiner = toString(i.originCaller)
590+ func filterMiner (acc,miner) = if ((miner == leavingMiner))
591+ then acc
592+ else (acc :+ miner)
593+
594+ let restMiners = {
595+ let $l = allMiners
596+ let $s = size($l)
597+ let $acc0 = nil
598+ func $f0_1 ($a,$i) = if (($i >= $s))
599+ then $a
600+ else filterMiner($a, $l[$i])
601+
602+ func $f0_2 ($a,$i) = if (($i >= $s))
603+ then $a
604+ else throw("List size exceeds 50")
605+
606+ $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)
607+ }
608+ if ((thisEpochMiner == i.originCaller.bytes))
609+ then throw("designated miner can't leave")
610+ else match getInteger(minerJoinHeightKey(leavingMiner)) {
611+ case minerHeight: Int =>
612+ if ((minerHeight > height))
613+ then [StringEntry(allMinersKey, makeString_2C(restMiners, SEP)), DeleteEntry(minerJoinHeightKey(leavingMiner))]
614+ else {
615+ let oldLeavingMiners = valueOrElse(getString(leavingMinersKey(height)), "")
616+ let newLeavingMiners = if ((oldLeavingMiners == ""))
617+ then leavingMiner
618+ else ((oldLeavingMiners + SEP) + leavingMiner)
619+[StringEntry(allMinersKey, makeString_2C(restMiners, SEP)), DeleteEntry(minerJoinHeightKey(leavingMiner)), StringEntry(leavingMinersKey(height), newLeavingMiners)]
620+ }
621+ case _ =>
622+[StringEntry(allMinersKey, makeString_2C(restMiners, SEP))]
623+ }
624+ }
625+
626+

github/deemru/w8io/786bc32 
172.15 ms