github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/transaction/transaction_test.go (about) 1 // Copyright 2017-2018 DERO Project. All rights reserved. 2 // Use of this source code in any form is governed by RESEARCH license. 3 // license can be found in the LICENSE file. 4 // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 5 // 6 // 7 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 8 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 9 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 10 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 12 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 13 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 14 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 15 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 17 package transaction 18 19 import "fmt" 20 import "testing" 21 import "encoding/hex" 22 23 import "github.com/deroproject/derosuite/crypto" 24 25 // parse the tx and verify 26 func Test_Genesis_Tx(t *testing.T) { 27 28 // mainnet genesis tx 29 Genesis_Tx_hex := "" + 30 "02" + // version 31 "3c" + // unlock time 32 "01" + // vin length 33 "ff" + // vin #1 34 "00" + // height gen input 35 "01" + // vout length 36 "ffffffffffff07" + // output #1 amount 37 "02" + // output 1 type 38 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 39 "21" + // extra length in bytes 40 "01" + // extra pubkey tag 41 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 42 "00" // RCT signature none 43 44 tx_data_blob, _ := hex.DecodeString(Genesis_Tx_hex) 45 46 var tx Transaction 47 48 err := tx.DeserializeHeader(tx_data_blob) 49 50 if err != nil { 51 t.Errorf("Deserialize mainnet Genesis tx failed\n") 52 return 53 } 54 55 if fmt.Sprintf("%s", tx.GetHash()) != "5a18d9489bcd353aeaf4a19323d04e90353f98f0d7cc2a030cfd76e19495547d" { 56 t.Errorf("Deserialize mainnet Genesis tx gethash failed\n") 57 } 58 59 if !tx.Parse_Extra() { 60 t.Errorf("mainnet Genesis tx extra parsing failed\n") 61 } 62 63 expected_key := crypto.HexToKey("1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d") 64 65 if tx.Extra_map[TX_PUBLIC_KEY] != expected_key { 66 t.Errorf("mainnet Genesis tx extra parsing failed, public key no match\n") 67 } 68 69 if tx.IsCoinbase() != true { 70 t.Errorf("mainnet Genesis tx must be Coinbase\n") 71 } 72 } 73 74 // 75 func Test_Transaction_Deserialisation_Height_1302238_second(t *testing.T) { 76 77 // transaction from height 1302238 txid be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843 78 // prefix hash 1bbfda600fa6affc80dae05b1124bf05ed0e20890aa42601441dbe0f6fa81f4b 79 tx_data_hex := "020002020003eeb724ffb209dd81013006bd371b1f0896e8288565a6ee338cc1bf8d49377c4ee6fb4edec941b469ff020003deec249bf008df50c4d6e57d433bea03e84602181ec725b2a5e26b39f690f34fa4344cfe5e0af6e6030002e8043835f159904ba847435bb264b268bccb72182103e36fe107c667c978c5c200029c9fe087f1c89be13f2b350678054326f83732e0c0ee3d1f679f6007b5d7d84f00026276a1056f82a31f15c8f417b47c7227e89f6084644f21dc84a6935eeecf19a5210111a67c084c7c71d2ee4458d2d7f213ae6b79a00147e3d3637adc084b098b5fb60280aef0815ce1848e3c587524f501f927d7dfa329782ed9b12447bd6c5435e6d4380c61394eeb91361a6c60f8a1414a3f001a3855c1e881348588ba5c4c0d8c5ffb387f9ff6646682c579ca9bcd82dcc79238bd3ac9cd1d7d95cae4f7e51e3a959e9cb8390974283a0bcd7022fb79d56c48456b7173f511d801116ac823d551ed740f866a06d07a4f86404a55f359659acfad67614d5b8c3adaf29cf07e0198faee3683100e0806eaa766dbaf09c93d577503e9eac4e7d1850dc9c6e8f7221be13f1c36670bdc96e7e6b973d409d5ea3f81972b844f083db6352c51def090cf3e0c2082100d30d5bf7f0602ae45eeb8361c0fc61d159e2b8581871d936a8d70e623f1bec102f63090f4b6e620fff2749a79c9556ee03cc02dcdd7200379e667941ef691d490f615c8405ab8b8024eb7f3b8a1f5eae543b0122db8321785556063e36a892f21e4ec30fd051afad9691d759f12aa5411c14257f8fd3caecb0e859dba3516d0a3ea16669bee122c55182a8673566c6afc38c93ace2650ce06b41a14b62eabea08a99c3b8b09f334b9bda5906f1e481b3fdc41cebfd7c45a139e8c156b68bddb04a7f7c617fd88e2bb066abfb91cb9c708c39ef6005b37a7f3472357dcdc500f039b15c7a871ea9c975ae1993345d9a7536bb3d8f1fb9d764643b354eb11f788021d295e331a5c60cd5ea56b85fc18840037e9cf6d25b5f09a9d99718a260ce908464ff548f0e8a247072aebd17e7b614949794f46f38b79c1a506ca6d567f0d002f9c9649eab343ad7da5755118623f8ee5dc628ee50f1a5d02ee13bccedb080aab365eadd3125fc8297355bce4c32d7eaef730961e958fbb6bbfc4022b59f909bbe7b7fde33c9f3eb0fb87531f8b24f6c5fddf12848b7539d4cb4a4ed68a2c093cc73a3c71e0992873f66030737a3d10d276678c28144e81fb40832d52693c07c96c24f680a627a8ea8f8d76f61f9403dacefc07fd3187102b32d4ecbe5bae035fd85b6ddad623ff9e081890e15d47398cab231cd40b2a94da28f65a6c36e20861c5a7af0cce66128eab0c2d8461c47d3a30698110be15895174b72e0fbe9e09ddbb9325806e682a6bab52608c37b292bd02836c8188751b13e09a21c0bcf607595009f6d1d5b8940f94a506ec58fd1b79c353855e0db2ecf3048c2f7224520e72cf02272cc7dc999f7675fa3269606f6be3119147914c73b1c0cb779fa3a60f144856042cf8a7d930d5d74052042a2590b2232383ee8fd44e63453f37549f0c50a6358f077cc7cc1af7e1515f9efda750f7887d04ffe728b1f1cfaa63da0f0aea5848a5871a9617edd9d414c0b249fbe9f1103a17fbc08d794f1c7660078100c54f3700d8df0a3c5ec1447694179039287ac8c392e884542a0e12413f4bd60c85aeac6b7bc0b51a419b3291a4f1234db9648b301e966b723aafd2381c45f80e3ba5ea209db729330091e03eda426bb08c6d0d15d8a31b2aa1470b1ec2aa9b0f4890bce254b5ffa8c07128d0450a8533695d774398985ddc7399db3472592605a58b9700066a060dfe2ae6681eb2ea195ae87c3859d1db28a12e99f166d2f508303395a4145f85a5c6e21b4809d4e95af7e2569ee835af71675486581e443e01073a7ab3ed80c083cb628447450fde4ab33e19c35d406b46dc2d6c04d24f610be25e852ff7be104369072715eb3098cfa4182a1292576f97eb8eb996d0f9800c1eb35876e019ef8b1f3f4f0cc46b7f25f50d0df7f53451fe17a8d245e0cca0022449bd26846074a351ea000fc9393f56022869498f2dc9627fb710b50ed1a5006e235da7eb3d8e930e7f9be82d16e9bf99d5e51b5067342f104832b262e6b8046519e6d914c33ba037fd94d1e37a251597e14be3a4a50743fcc56726a1229c030bb3bfd3015fc95ff5a128d586d783e68bfd958e63d83a9daf700ec22492cf06acf546097351b35ad68ba245abf4169f99d253f616c42819218987fffe192c0e9c7f2bb74b31e00ad302fb9cdd8ee3ce2bdf38bcf2bd76921c780a9180825e0e40caa0854b19ed6f007a248517d244ce34ab8e0dcd7ebf18a61ad2d0e2b7330fd35df106d1cc436c318a6cd88c0aed3a7aec4307cb7e6bfb99923ef09a71af07536f39db13e261f61221d3302f6757214b0c33aca327b658d659c5d00d8e5902bf773d09c204c941789a4168200fe897a465e8c30020f98cb66864f98f9a46064520a4ac94ffaa29477b6cfc5ada48b4d422e64f7768fb0aeacc15b5c0038c070ffc28941673707c3bc49d3979364a0d50027a836a910390ce80b651c2fb47041ad40c202a3f982db0502cb834ba3b8642c2e3395354fdd443227f954063390cd229b6e84d0c579ace647f83d0883fd77628c1329f7942f91c0ca1a7916a720c3491f23a7c9f0ab21ff2ee74729d38469804894f46fb6cd217af31618eb1b002ba4483a786b9241325c84ec7c37e9ed4748d2f802a176d156f293f05e3cca10ab6ab08b5ca156da77f5010c78d6c237984ff550a7ebb9943b3f698bb8d61e80ea5b1135aad3d386a6fdbfc0163517e5eb7af9d926819baf5d9166298c40f100ed71d97e5beb3718421c3727fe5cee2a2187d829f7005156d65aa4c5fed4d0f0aa82cfd5021d417b53a64beb05d519f3b39b509c02b7ab6b9033f195ac1c4ab072c32e208a70b20d554702480b9a344b7a44126e744abaa96f1f7406638a1b6006d7765ce6a9206029054246bfc2037deaf59febadf7e3e757f753cab2465b208ef8a5ba15f3798214a26591950ba3e2a737184afd6d98f5f41c57cc6cd9fc3032c4ce600de91f1f87cf360ac60742d145124a6e70d5a4cdc1dd15fbbe4f612011b72deb21f734273a9d558a4098b1194dd0e71b27268f3c6cb84854e79cb7300d5e10322648535700994811bc6a96d3ebfe84a03546ef69ad6aa7a96657d4d09de424347a2541cd611205d4e229154345cd7afc82b9fa424c173e80e37e5320162a77989ee8f120f08c58edd72a057e07c4c879027462c44d4c1f3de0fa90c0e31df418ad8724aa58adc5e4452971e4da973acc8ac88dbf092b05ec33e9e8606de4584eba088aa09bcd2ef952e498a4c5ae3bded5f6f76c55901d5e67be5840971360ff2e0317afaf855d91f67d7ef2673d912f21faa9bda118a7ccb8f4c0e005d725c22ecddb8de034b86f2a150f522bab5e3c8880648fa8a56891bcad2e908c4f0fb1fc97b1b0523c70d5647624ce29a968ad2aec976cbccfc1d3770b3b80d9a5481a095ba7ecf5edef11c258cd3ccf1e2fdc2f6e6699fb382950acffc8b0c9476e9840debb9e5689a0e44721984970f446634c572a4e5e4651bdcbb1eea055168f8c390fa90def1db63a2cdba06031323d98bf475b1c11fa0180ff989e80b428a66e88a572fb2ce9bb49dec2ff12721ebfcfd805901d90ce0f12d0b58ef0e7747adb41140ebb51f705cf6a37c1f202668c2173367245ec692d941835b6e07774a58bec6a0a40603b9374b4b85c1be4b6d3e0595f2e0e4d2449dc98c164d04f0f9cdffc4b5fb42dab130ddd55891a7c08aee1d68755c87132b5784a5cc030dcd13acda0edf0f8927a6752cd287e3eae2ffb185cdcf7cc5688141255c9146082ce3d79db8735c29fce4430295f4295185c2acef84a38df71ebe36930df45707747c28c129454f8f604fe628e72c45a8954bb90d02505b853e015681da4eba0b91dbb1a2e30f2d539e063cfa6a1eef48ab585fd4e6d9626075783a6f1a47ca07a03c24567891eebb799c29e33d5739bc03c4080a51fe2393878b8ad4c821380343c952592cad103ed3f99383ecc6192ec2d8748d843d869aeb845c224198360a453355dca4b84785b3379cff04899386712f2bce9ff3a8a5c09b3b6104053a0965734ec5d9955c3efc379549d7c516756bbd3ed7b553c70b517c061ffb25fa0d44f2d3c5d6044fc32ec028021774d7068cf70e903466bdc329e687ff55cd340cbd38d5d6d3ca60742a013d47d42dbd3e4b55778c9d198fe4ecf1b6901774c508d92457bcd4605bf15b075c34c5d7fcea39097a56e6dc6ce30d750ce1388f3600fe5c1d514f7c1eb45490aeacce197072aa4289f2ed9d400682619271dab5e20c89e7123202a1d5dbc0ed27e5237f8c8920fcca8d4903c8854225679991922a09782c829ece65d5d907426d97d3a32e3e3c899fcf23c35c5609d297c48d6f5c0fd09a5b45bfad4e57db448d85865c60566c9d73d069506162f5ea5b61881c910ffecebb221af9ed57b321b89e9973987b8c2c3fd11ce26c395cfc45e2793831051603c558ddf8bcb6bf8309fff217cc3cf064f86d97e9988a9beca295bde27d0e23b33c05d20cb48107d226b5673bd498a83a6da07f9ae2dff7cbfbdbd08db50bf0c660a58af1335cdcc7dcd155f49a889fe4e7fc840adac45659cab56f792207e5e406bae5367e630f258718a0cb9524f7aeff2fba421f2bec888baf64f1a2079f2d87f20bef4a30cb7f6e7b35ff316a576c2f54767e15ba4ce80857d918d202254b49a0a062f7772adfbf2bcedbe2cbb145aa1f9721d7638638c2e752a53b0ca55ac2e537a4dcf17e13bebccacb786865bb2359c6197f7650fc5cf5eb56eb0e81015a8322f912dfbe3b2be2b6281a0bf07ba9e9ea5c2de95abffd3e1f9f440158b9d5fa06bb8bb363f82a61bf7b63a349da071f89301453eb6fb0089ef1fa07d7cc99166e9f32975f9374ac18cce9557c2fc029c6af1725c54a398867833809a7f7151b6e5a695f15d322ee9efa380dcea0092fcce0c3560ee08595897569096823962514330eac2e10bbd15b99f2e0df77a32ff0525fc1b1da8d78106bde016373582c7358c203f42f0cb14dfda584cf61a50a79aad217ecfcead6ba408609bf9484b867697fa052fb2a1024a285ea6c468b8c1958ac614b8378dc1374f10953f81ef9fcbe91d7508e09457ad8e2b6ea4b742368cc2fd732f52bd10369690f9ec6ef59a26e2edf53249cdd0537d851d6a4be5e16f0fbf25677983a9e1e7a02569e221572ab021b9feb43256ae6bf145d0a99347994af4cc71d01fd4e27e80f84ecb3902a0ac85be6fe02d919dbd8098bc4c6ea1d5c76af2f45ed2e645dad0802b3dd6e9789bd9994ea081a0f9194b0a0059aab9ddf048a4302c5e9cd24d20c2d2dcd3e1c2da87b0f75cc94e98f360ff28d43368ec7f38dace3c8808cf4d207e9acee6b0d4118412eadba5fb30bb1887cdcad039f13d797aea1979989c78807c728999ed1f323602940cc2e1ae9a1f2d75ca40b45fe734d6e939b0915b61206b24e110ec8601b634e34ed9517602301da8feac7fc02d5d788491a72c68f6e035013b586a8a59de99d9c4f5881f4f90a8b9d52c49e3639866a5cd0eeb72ced08d4dc7b5a22bb410c0621a0e320fa6a71e071586e63c95daef4885e8ba30d9e091318d897eba826d361c3c1ff4c87765d30c6f1963ba25ccbec6bca28dd3e420a99f6bdbd125624304d49888f08138e1b865ad8cc933c46dcfe6ccc6a4ad97b025da8baeaed55d4e070cd06e49ee2b1442d1a3122e11bd19b7401bdff9335a702e1c426bb560eef0a72e95b7f391e2fbae1d55ff33f54737430b64eaa8645f40abfdf1a64a39d26a9b1719b344049aa39ff5428c8abc8d24f16f7a7365c26be0401f679cd16257c8d02151f5f85c319ea2ddc756a48b21722e500b0260c117c0042b5aba2c4dc66397998637799c3ee1a56c8cc932d9b44cfdc194a4306565000f44fd018c3049b99fa8fc250621ed566d6c701391fd537b1380a02380884ca00889ae696745a48bb3e900cdfc744cbd0def9dad9d45f30a7ebe6f385bdfbab0b44260fdb8682feb4fda0c7f23fe11b5524d1e4ad5752e6a82224658afb73ce0c1bed7afc986c0d77fa345bff8b775356d5a7d243441db47419c5538199253e07cba7eab3a8aa961e9eba40011d52fd268900135bb1e23837393e492f5e79fc0da0d18985295b0ba4cce4a1652e9bdae4c7d9201ee0c71da389829bbf2b0920000b1958330e558627418250e1920187b6fa7d5a98275e85537c8347203ce26b031cf2d67f127f0f49ac9c3577ccb85626bb7e2bc297968f99a46478535b59eb030cae349502940c272eb67aa17b27d5b5f98343f763506d371a82a8d89b02830193dc887380efc30c914973a4c3df231e5218649a871ec8ba088e3cadb5574f00f6da7420baf4c343c79786715c9cc6c612d605040fe92a62fdb93d2319fa3d012c13e87a3383022542f4d6f881b3c5666b3564ef4abd82f64f2a7be0a15e500cd66dfab447313fc359b3bf4f7828f12f3dd8e023860ed061dfb0054eea712608741d8c00041a56f42f356be5d112dd554844d2d9daeafb15e1b4aa54f9811bc2f7d6bf6c3e19f5dd448ae9e5464601b8129cbdb2f71cea6d712a042deec314659306f4047432f827793cf10a240addded048463e1fb65add1cab4422ee98ffc9a8f9ddfd31a78ca3dd7e0cd74ee289cf693cbcf308bcf731ec62ddd8e851adfd2c3f3b5f2dc6c8103aa50fcffea275dc56fd00abb3e12d078557659dbe5217588198724953724ccf5857dfab5529c74fcead15df94de90c57df3d3c048a1137ed0f2df83df489a60d21279ac87750632b55c93493a4c51e7dab476c5ac29423c134ad1a4b7f27560ec97cc6182f3f349bdb2f2da0a24264fbc723c0850350b302bf39a341e5056cd55631de2c30195b2f87ed5f1051de877d124df83913a747713e0f4258a6a2c2be1fef3f1590fa63ad5857ea386889bc42784e037dc2e72442c5b2e2a6c02a0c7e5f0c65fb7865f4094c40910e88866b759a6cb1fbe5cd83efa1f93ec654ff254f9ecfaf5ae3704d3a51fa5f771e8db3b822fe3f0f3063d9c1c8a460e7ec8159d0a1b300d6369448dd6a249aef77dde1663fefc6f1db67204217f296bb62fd3403f7470ecbc854e7da02d3b58efe072cb96d7df1f4ed95c2d71892321543b9ae9a83871850267765f0d3df67fdcce6c0ded21eb6d00357a5b09d93d646a5af7760d45996b67b379510b6ab466657d014e171936c4dfb1ddbe6bce24ed78ab33a22cd562eaf86c3854e33143c2ddfad4d991b060a61e168cb48493fd96b3c8d3a6a84df5900b6f762f5a4f783af9a923bc4fcf1d423a2dbc395807278f9c41e317d265cd7d0d0d4f844b07c6991865226a1b9b10b33a05d818f0ea0c5c23195df0c56b79d4ef555a906d9fc70b2bcd348087ae3435aeea6882ae2778fc4eeb95965f0f309375d9dd7b4689f4becdbc68b88e432780b3da082e15232e43112c3f5b75d88e80fecceb74fb13aca9c0b9280d140b2551b2f7a9783ec582cd97dec62c3ed831eef3fd5469c2209ef3e1c0d230eb8fc49971e627f588b04145534b8e095fdc6564b33e78ae0ced0efa355b0ca30ff2b8cb46fe22329dd4e49ead6fc09476d2c187412e15e1c607ea5b1ac92853ef44bf55d2119d10a4d53a3bbeae2bc26314416f98dcd5d05a4d672de90ab2903367b0851a2e397b3eff98e51a4f1d7b76e11db06d3422c7f9a13dad93f1eb5a45d7168e787b808a0144eca91a1eaf95832e3bd48c109e68e0aa02d3a055ace4973906817a61c373c4c3d7e7c011a7c36d7872ff4b9e52f8be4b2dc18546dee76b5a4a27f204b34d5e81af0df91507975c64c7ca7d8308b6a07cabf0b979e4bdba1eada0b71ed162561d6b6481dea108f46c000b4faedae3971fc0ead00abf5d59b0af7bb2dc7781cf271b8b7130b55fafa1940f2542eb01b8b3c19cf930be56aeb7a8a1f975d502d9dd9499641ac067efee8bbff7d87ea50a3c575899e7e35fb687f7857b1e213a8476980a2bc04665e3aa778614a6510cfc51777dde2d5c3dde73d59b319bbb90ae7e2f2ef4e6731e50fd4c2c8128edaf3f1b1a2eb68db169c019ba882ea0f4eacf94ae3b9aca31fc714c7bb42d7677afb5d89cbc1448e78a9288f8828e27396dc7be417e9979d6bebef552cb92574d2bd3b9e615baedc21359a19a8aad4c11dc525bfaa02230cfd9c47dd2e36cb54060bad16e5616feb0b60c2f376f652c78de37991832212028480fd654191dda6a6183e5d32c49145837ec230a27d3b9f9bd11adb7484db8d0e84a59814a2d32165c20aa6e5ee1927dbefbaea3ef4eed8fbdb5ebadc0c5a5ab6748c3141fb3c177368e40642275bde104743b2c1d04658b4f99833d8f6447ee07009318463326f838ef47bfbfa2cf243b769b65ac2f5048a9f51ca1f44ce3fe7186aa13821ce6fcf93ae6fdb33ae4bad5fbf444e3d632b6b7369fc26fbafd3e6f88fedccbf5fc9f9e31f0b4872c839edc3f3caa40a1188f6f90256792811587aee465e6d3fe1c6e2c9eb1ea9105e0aebf23b9b7a5198b1577ffd0d843f3450608ab52372a0512a10e1727494a41e7be75b36c577bed08fdbd7402f6eb9560b35103b0db52ca07b3cd9cf6785d00c3b1127947562989424a3ece30565ac16a23eedfa61e8dfee3e0e1ef3a25cc8bc28b2ce65e9ec13bef65a67b65f42ac0939891bc8153f5984e5b8be8a4b8276dfcbf3d723f9a7e0511188be7be2ae3f8d32cb54bbd101888b8bb201b2b7aa0e656ef80e4a030587d625f4e4395df4a8f8dfd0ad2f4e0d9b00a0882bda507f4e0bb5d351e4258965d0b29446e97a7022e90983714bcd15b16eeafaa9ea50d4087803ba23a33a71df4d5b338d5e74802c1808c0f52dcf528cc16b558a14bc6a20a71ea5e658d401af41fbc4083759553516d4cd6beab747648680cdd94fac4c094dcad5f1cb36198f33cc2e45a6d4c12db6b51e09e574e405c2077b518a745559e3a4f72648a68051f00d28739d2f961f22599fe82f5a9ea5ab53aeea61fef84b160ee6f49c60e9bec72231de7d7c1a745540712e2c14781dbbdee83fc2f8390d51f522496254be97343cb5993a030475acc1defc3a7b274c2c80eb51ddf3fe045e472e162cab6cf46f2becc5d82dec92409dd097fe5bbb19ef5a40b796a9ce2f71956d109b87499cf5c57e31f67b9087928f63fd2921af5d869e105fc19acafc9eaa92e512f6740c441fe576c0a322edb56fae2b83fa4f36f9e15a7f9c55177552acdee1d82a2d75974923a5a913a92952ccea4718e81f2894f2266878ff2f5dbd7adc7968f8a5ff3615af7c013068fb21947793563c2a22e4f2506637a98ba43bff7154a0e81d544bd53e023ca63cba83adddd150eb432945808cfc5b707a8b4bf76d7a9153777220e251dddfa4fa7b579f21b6e5a2277e1ea3f41cc041c815ffe20ace553169160c8e50e2adb8f472611adacf1b72906d8733e8e531ff6d1a4590c1927071ad9da8e540087b72f21a9ce295047e88de99f09912945fc1f8fb4b4e46c4c9c24153f35bd05a827a82bdc2b279c88e290ece1ec45612bdbeade56543478a5563f2a2397cf0a8f5f8d31556956ac6971d7fb7ea6b09f003b0780700c6624bf6c2ae17f047e0eb9341d3e471ad204773fbe26fa0b0844c1fb55426816161e46682673c192f807a751cd20fb673ba602c31473e0a806465137cec604e5c8fb0aad1c22c402bc00663ad679751d5bd22c918c73365365d2506986eab05ea4b493fc1f362e916f02c7df044eb775a8cf15f2af7cfbff6e59456b5e62e990ed88f54effbd3d33740ca6197d0934f2b25f404a33dee98244b82566f577d05033b54945971eedaa0706b01e233358a1469a0e66bf4494c18c901db26eee0ba73496eeb1a1b7665e7a010b6dfab72543f3f5da3d228f5c7cfc8e368f47cd5052102838fcb471b67691023ed28e08c33aa1214c6418dd14307a50613748064481d29dc157e5e0bfd31002f163f612a6bb3f0c10f6e4db2145e52c0d3c8c3b87be5ee717373674b5be97078d05ff36f517c70caf12f75b5d8db78efd997ff16aea0d40b621586f5253b60681ab45216061119a4e0b5e854efa5793d1b0640126e4b3e6b86c6452b532e50cea7250c5b91ba9d280837ec629aa7aad27f3308dd1a93f46cceb90b648131c0b7aef37c58294db0db1dd86f962e557c9b306784196dcb89c3b91830152167a038549c28a8f251c51e7e7b4c20256a15455ab3474bdf9358422192e83a8557505ec7781cc474509dcc2e3daf1cbb8fa5849b6dc30f8802c758e144038f34eed0912e162bc006effa5d45a5acc0502a04d86ad4e9928c38c0b0bfd81df4eed3e084e06559aee02ed4b93af956d5f1acde0b5b002b932e90aaa14a5bac05323e40f70020d443870ddf0e42cdcdd8a1611e7240a209b836ab7599c984bd69311100a290cfcce0eeb9f22e6953ee84d93f668d46ae9dd986fadffc1dd21134b09e20fbcabef1bbd770697e798cb5123122dece399df388256669b326b05c0325feb0d6e80db9b63f941e26e61e7d93e1248b67454e5e44c86826d50b61807e0bfd50ddf2e800dff97a3e49824163266ab4601df8f81ce7fbe89f9011abb2d76aaa50d2f39d787740665a841be746d6426c3208323a9c522dd7491fb1b1ebfaa2e240af36142f584853d825d63f31c876e8875dbe72043501ecc83c68b619c124e930f6e4145245d7442c6dd3607f2b2328c5f6abd8d09554232cc3fb3fcaf7d240b0997ac61c7fb1b0b5cdeaaa0024086046c793d38c6c103e28dce4601b437dd6b00a27a8a086b86d4bf9b5237ffed7eab2f1a2f4c7912d16f7de386ca53eadb8d0958fdf65e2781e39ecde8355e3a3e885a7a3099971e541a7ec822caca02691d02a5ae37b8eefb72ea430ec3325851bde3e0254b710dd63808ddf2346239ea86045e08d822002e04f85c597d581a64729d39b27f6818f8402c6223ad5aa1f4eb0ce4e25e8d1a13ccec340634a29b9a4ac0c22824654bead61bf8da0c7ca46bea085ed7a4d176d7d777ea9d41e6f661eddec9f4a931aa7b195851631860fa10490f4eef0aa557a57fd351e33b71b01de720963a00872a2177a3f102589cfa39af0f04238be5c8b6c53e1e361d9241dafaa02503ddfd996beafe4feb989f5195330e0e33fe461cf05335310b2c97a73b36b3226babc44dbf5134f256d03c7386920b9d39afe6652bb4833c2c21e195d396f7f67452685dbb119aab7f1556a7ae9700937130c4d3ee3a773f0a69a0303dbc845a8a885e8200221cb0971414a12101045905c4175f70af36565e20bfaf81797d95db17520ce2eedb6a2949bf94d70106803172ec56734ee33541f304afd8539d5663e19f06597f60ee81416dd4acea02edb6d1d2511077e5c5c30094cb4ff7000a55a3d323b97dc6e64dfbac4dd1ed024e7ee205bb7cfb3419d76c442c779cd972101c93708ad59d5d4467ba74480a04c8b5d639f0f1917443c3119ab32b7987eb39bf40cee8dc96aa16b3f22ea8220e9425ec1af65b890ace9a55cf8a80550536056793f990fad922f470d6c142910be061d758e6b65f8fc2decf53ca47a5a3ee7477e0b6ca777cd9591eda107508054d8e409cb2215860d76d613d5da0575b783047691594a2683b012a82c7ce2c07b6ac487e25697fc7c08ef75fb73f40a841e721a9c3cec03f6bf231d52e15fd06a6b6e7dc13cfb9056b1c7be6dbbb810beca8cd7e5286a21ac7aa4f48d6f75b0e70e8d0f989f92da1e920e57b762326cfb77763679cf674f514fc011a14a34e0fef062713f8ff6d71d53d9fe1ca1a8f9b07d1f18da95b2022d303b81ed4c0960c7f246f06af8d8595d53fe421b50348daab2aa056414786dad6759bd1d31bd10ba266e53b681e85b796b00321af39bb3242245c5801a15926bfdf783c6c14b606f02a4ec21abd5f4cc10b747ca91b15ae0712b780f3aeeb266b5f89e90c0ab7090ea4e164888a88f22b1e9ab3ae320e4ddcc67d6f2be9b4b8753080492dfcb008c87148ca6557137ac56e1cd65a28f54f8072037bd6e68f5e07020849da595a0f277f8cf04a9cc34f21341ad6a725de56f6b612815c2a9df8a703acdf5456ea0267a60965dba6101e9a1b746bb88fef003d75235c40bbcecac6160b62e981ba09f00e8245c796d5ee698fae8e9c43814aa7a31cf32320d899395c0cc75cae9a0d48f9974dc93705b99ec8f691157497f339b452c8c2542aa47efb557348ecbe0615c9c7e15d59ef77a43535845e13fcc12e719369ecf49f397c774dc3009d2e0d5e185e352baf6cce06847598b1661e83f10ffe989a6be95ea2e32296761d5d0bd115b9a4d236b9ef95ec839dff67d503ce563718f037a95e2b74cfed934a8e0d7d8d9e7e850d40256157d026dc9c97dce1f4ff5cc75e3268db840102f431320672fd210869eff22eb11165ea3bfdff721c3dd9da0ffecd31cdeb1d70a2e38e07f84f72aff200234323fc871da729e6a0816ad67fd5b9fa36b135678b21eb550926015ebcdec6d3e5a2a1b362d61ad64d81a17dccf461af62c1242df1666de207fd73e2d8056ae8fcb6c7d69fb2e7f412ad324c514acef1c332f32a5f674a150bdac408ea1e9b2a22cf447727dd47dc7e99f779fcddc6a540a4f2b517b87afe0d20e7dff2a3c8a44764b7ac129a0c3717b66e0c899fb243f512cd4f3b09df620f57de6d4183f0240b1305e21f45f1376f09f61e7aed72ebb0ad87c21a67e3920aa07f26d8853123574512574b8c8fb52a25e6ce01c182335f4ea2246275fb9b044f235d932110d33074a5cc259e12085900bf15a0a72a39d452f54d8ed342d10e6196dde7ac29ebdaf20f2a7b71365ee276bb2002c29a4be2ecf12f9b888cb304e67399de77e07eb629a468e5fb9a1a6b3eecf39dccc51c84a3463d3e382fa702fc44b7679ecd9fe143db08e10620ce22f167af16fe9696d8691c00b704827f025eafe3252f725e0448a5bd30efa3a0dd3a42a9efc2fa0d106e893ab1cef1f70f28419e55bec0a225937a8236b7895d561911c7a03725f80525a327eab7e68702a0595126840cf32da1924ae5b5a63ffc5eb09c0f3be847d70a65d115a570e70053ccab30905620bfd5729dc44d46d53070825cd0d6d02c144575e9765f89e50bd034b8ca69116e7a993737a206f78dab89a564bd1a12d5ca31d4c8b845e3660dc6261466baf39e6e80fdd60068047354950bf17a2c0935e2f03a6a8a1651b60bf6eabcacbf5399f4fce00d406e78ea9826c6229e619c27f762fdfbc32a2b490c5d90a4bca73b5d8e909a7cc188bbfdf4e591ef66778aac5f0389ae5d018fbb0787ec6b6de0ec93f78dd5f6fad9b918073bdb42edc06b3e738b26dc98568f1f017d02214743b7fabdc0bf8230766ca711e8607bd62b271058add5fc70ba57ae0ae3cbde974be33941a6642857b8a317d540966efb0c3d231313554fe9edf38106cc5048126b612ae74c6b2733ef911bf7fdc028c3d4c120a11fc761da9b73ed0c70f62f3964875b65d6c40ae6697ba349d8c540975335ef27bd2a3a5571117a0b9c46c56eb9d785fc0d984166b4ed4828670f97f385edd5c4722dd28fb0aa820947847d3e1c0a41ad63caa291975364d57b34d4176ee8201038856b2b0f664a04881a39c4766740b4764eefa9e830abd9fa4480242e8a6b99e44c3d5e2f7fca0829d8a7e38fc38e5326277e548816ca8fff9bfd538da74e6016ce0a759cf89e00c5792887b87b7f9f142f179a09f3f1463ad255a7049aca6779404283d8c05a01445b65f58b59ff19d564fae624cf809f47b97a26ff3ba9c02f60d301428e370bcb2ce4096d8f11a5704eac70957dda8f247ca2fbf3a88d39d4639c74167eb708703a5caf07008f1c1e43afe7b640abd2bc1eca80fdc8b92529ca142dfe005903721f05a2c6288da47a2d6b33a38e0c3e92b8e95a057c2020ddb3b84f3823390aaecbe0d73d250a65804920c949b9adf6cc634977228f6ee5f530f7f4937ee60038b79254b5ff0ed115fca8846458c790e05c1e4db7ff0af31576ef57debb8b0fb4cd93509e8535d0242094bd7a5e34d2ffafb4d44c218974b0c6dd63ad17560f3e34eb946fd4c2371400b5b19eb6bf85bca14a820c2a540a845439b03da3e60b3aac4d7b78482607451e4e4ae4d4127964dd51802596b678981fa937610c0a0d7e7b286ffdc42de9b0d15557b31ae167ac890166c0d9dfcb2be4c07c94422602e59b4c72b9e6c80facc95f610d3393e130fc5825a3754e64c25cd7f3265381046c88b76bdb2e507bed5a1d14788872f887858af2064851cc5e758d47a71d4d0798fd422f9cbe041cf31bfcb7c38aa6705b589cac5c20dc38739e8eebaea3310d6207837a8e8c72da07b30fc25b9ec80f09665374266335b3d40e722e22fba709536e2d4d5dad2bf70b91119cf8f41104ab97d39366f42e397e7a384dc4d5df0d50cd3435d7fbf0abbd119b033b51e92f7517cc3d123cf1534fff48a9d1d37d030e88eb48bd9c9d35f73224bf6b620a547ad117323a224e07ae50a6dec817d10e0194a7ffa2ccf483ab1469364675f146d8d163d45275d6163bebe53247852102423f007a5f19fe8465b96ab452f520e223a060885c475553a7958836030af304b2e52e561dc93758ffc8d917283e3423e5126bc2b4c065f31afb480117f9f70f21b6c37373af63c7164229d3f3b8c62f58407184a68209e5cf15816e9545280a59da6695f87bd6e730701126445ebbbaff5174adbef16df384a0a3db952b20041ed8b7d9940eeddb47d9e1632493f201c19ee52d0f381ac2ec798e538da6a00cccd34c94637a9a836b41ad39bf1301bb1fb04c8138658425373208fc535975093dbaea9732fc8099470423abf96766c0a02368ef1902738f684d4fb111169802c014a7bbe008fdd42dfd3b5eb4ab1cd21bc66bad7cbee1c54cfda198545a91093e27318f81006e2d17d67b6258d38cef4737a4d4528ee94bad8ea62103bdd509d7a5836f3651dbeecb9b0061a97e4a9b67f176e299c5fb1cad24e6335c9dfe0b7dd2c0249a97a83cdab9ec710efb9cc7e73e846e8dc1cdbdb3a1f034b8d29c04ec877d426c0ed2c40601583983abac01290472addfee286c252b66bc3ef474032fcb8c0f70d54b783b0a41ac4abb65276627857d34fb6a5834161e56d0fc900bd6d562f70761bf19e73be97dd38d48cba2a827b145400f576e0269d536b34f029441e8f26c1bbe172db8b0f68bca955355818e138e1b593d2a942af7f362cfc1a97762db07c44f9a104c67288eb01edf674fa018e558baf7a77965fde40b10b031aba31e167e9f2796f1bdf132dcd2481318ec44120771fa7c4cac21aa41bff3203a0329735e2d4671f12b20ea2ce748a165d60030b413151d8c263000f09c85ccec7cba4c2ed275116b3b22fa34042b86f5e0907a51569d979edacc16fc88f2dd4c550e16fa1d2a55ae889c988188d4477f49913b1826398b9e3385a3781a55d5f1b564243c2e2a7fef457e6bcbaa510a5f860964dcadac500d279feb0a3fdc02e47d2994d4472c0c14f7eb85c8ba96dce6f3b756c4c8b45080534ce821ab48e79ed6a8d87992afa20cd9c5b839b796dbe89db9228ab71ca2ed4cfa2638d24aa1232e584521b22f259da3df7e328e6045662dbdd8fd94f22fff9360fa035392cc83c2cb882e4cd2264135974894c50d8a8de33980727b0cd0902ed570e7aa91e9f448d01bcd5f47f5f0ef2f0b1d73c5dcd515a920fbc4c4004f1dc361ed97ccfecd307a9263622bc1679093db7e94a1abd44dbde322928c074e40ec54df02ff96b0c5c2bb3cb3f0b0762f2c9e8310a896ae07bdc4c0710ee67ecdc872d0827df6af37d9fa5ec2bbc61afee32710ab22c0bb3c8d3e0e6b04024c0a7a1bf94ce49e440e92691ee06673f3737446a0c2feef4e05e5b71bcf6cca596ff1871f82dc2da91e9faff557b1ec87eaa94b6b12d5ab6135ceb8d3e883cc7a366fb4aa4f0de7f6c84288cf561bc57bdd3d93aacc02fa957d4d9b3da7d255820dc0fd68d43fc84909797ffde36121b6883e2c791f0b0a0a6a4b55de118944abacf13a53b9cfd3e5b51730607c086b51bba8bb5e75a7301dd70cd4f96f8800f3a55ae71ed3dc41eece5a49290e52f7c8d80544e35d644f0fd6fec77700bccb34c88d496443918dc63192ef3425c341cb4e1077e0ba7535ec9ea9557f0441a8cdd2cd75b9aaa8682dee2936b517dc2a88a5e42cfb533bcd843c84447a9974ac276b8435b56d3e0c821f453ccecf4e2eb9c34c1fbda975c5f80d4725c841ef548f8df440a8eaac6945b2da8f9405faf93f08dcce4006fab4ad073ee9b200ef3bbb67b3765a579b52dbe48a346099ff87ed5864ba930ab0e54913cb77734509bf8e7b7feae8c2426c00e859ac1e784bef816b03f6f33ee076cff5b5df52dd3869b886ad25eba7575089204f1c0778fa3ff59f9e10b1ce5a35cdf886ec81414334209912ec2c05d7fb7c3c5013bc49b1a4b303307aa34204a956d17e01e12a0f2148a4d001f32bc455749cc90c88264e913ded95342452dcbc9b094f43ee3426874a09e3817d3d0aefc6819589fbe70bfce4c60e8a86baac80b558bacf7d4881b47035b843fe328832a3603890f66dee09e86a25c6ff9ef2a4fad5576a363cfaa7908e92aba16b31ff13b6fd021e288e3a5b55bf87400b4b137822a6e29ce03ed8c4c75f5d822300d9f66a1187f36342a5d23ca3106ff2a8d60066511dacf4562f6ce3ec8136e041cc54bbdf92b88f3a742eed6a593bf208de916dcc98c4a431dd9f07cd753ea2e11832a05a1293028c4f580225847af81bfdc83cb98854a6b1fdcc1acf4da874ee6cff5008f8d2602a05baa52f0bd623515ed0b6da23dc8717aad25ecb076dd4933638c787e921d99524ffd098b59b156ec7884bcc4091254c7e57cc8c605c686596cb212666abc16b3883271340eb227388b634d8a07272d943cb7ef25b66f52a2c1f389edfc8ca77683f7ab2b8dcb1174bf153ebe52aef84626bafdac37509c11352b5e89d7365fe8545a568e48b8420f0ce3ee4b0d0da4c4ee78b1b7b5da5f466f211d0d1c94c5a2f1cf3df3b9a25b75f970496b6af1ca03cb1163f90957fe4251b555c26f062da8091d9351ce945acc17b51a0f56771e157ce18fd5227c109c2d6d05f547861edaaf46be0fff588e57ae74b3881bd7e67cfa26c173b87e7e931f531a15de7bd80c90c89110db2a44d2a35264857c32a2cd40f7324590c1d5a78213f55366ae144538c65f5f196b0aac00d40408293d2d1f05394d5cea39648b932e686d94c40d622cab355fac4df183d02c1f6b95807c778be3789a05cdf8216b77a1ab6aefe06502072a64a3ecfbd6b2d6bc4eb2d1b309c5afc40c1a7e31d10b21cf770ff7107c38d7f90a3e8ad6fe3605c58c4b41d99d498733d9f4f578d27b6e8489cc800f01d9fec1c4ac856dd6e39a168dabc3b60c60a5980b8d7b5f2d3d830ac25356b0b352a4d95db438667a66f0260af56d215ff8fa95f4adeb41a7b457ad678f935194d03746e8c2e5ae316b201e4edbf3c269051e55517ceee54abe3e2951521e3bb90c065db8ae48731a4a05bcf8c53158b477fa62be05804849726a5ce2cde9165adbec38dd2a6bca7668c5ff5813c570df03a32c7c51d389fb74b8c54eef4345b4d019b92186076731d718d58bf44eac093193f3f881e1775060e5dc32d87a685569f8fef839277f0435231a6db0df3fdc14200af8b83de1afba47da9fd750a4259cd2e16ea5d09a1cf8ecf689777a1d3bc60f5e0637c1d4412ff010ce5baa2eb4e8026bd060080dc90e0bc14a70505a81d70fc5cde8fd9f60efb79ca51f50e746173930d5ebbe57cbe6097e3cfeb85a2963478d9a93a0c1ee1ebd199ca3592cc8a29791eb94761ceb9b3e38fe4410d254176e12c271401ed271c87560fabb8b3ea14985c8d33bfb651cd4c22f036b714c25c91acb41ccfc4dafcc14ca98245ee43d4f36676768c6acd6bf4494626fadd481b50bcab890068588f4e3f7269ec7294e2f9d41258b3711407f150de3723a5627e662f792aad2eb539e66b8eba370127b37168839786d0ca0da4b54cf9a3718352c501e3e08a123ad4f1a09ae0971a0578b4d50ad88b070f2d510b22d46ff57f6086bf497fd7064a0aa98d0946d6cd89f9b46fd83a5a29dfb7437bbf695be2c67f5c083ff76108b59d8afe2c3cf5424606926e16dc783a5b268492a8ba86d157590fe367ef9f0ed2d9a7ef37fb8da8dfcdca89432308f4a45fcb23b90927995d4c2602de7fb5019c181049b9100bb9c9ce1a6a5a9c5528aa4be378d6c25ef615866e6ce26b80000354087ee9f90b04f17862688fb8af1f6bad772aecbd2c7f1a04887c075fb20fe7ba852f6944daf39acd2bbfa3909f02819f3865c651f4b9e1904636868f1a0aae0a05c8d376d809d8d63d03705bed27497cc83fded6886868f7adde811a0b0d027ceea5186c07ce3d43a523a5d207495414d8a0aeecbef892689ca9d1c2aa00ff3b553516ff3a72a3379fa7fc4a1bbadf1ea0f664782d656c590a0bfca8640641371c0f94184fcd8675ab93c31df18f3b7c40a78c0bbfa5b3f2c4e9eabf9c00a17371e2387df0bbe9189b9eaef6418c12db41d14cf83e4dd0d3d95b7e6d450275705e9c2ebbc0c5969506bf390be7c7889f341e28caba054df5d76402618d01f256627f58e792e45caca4b32587ce2a652ee68601fb71e6b89fe179e77b6009a96e72a03c1996481eb993bdb4b7d73ad8022c170c7d78f20de23f0be11415079f0d54979e319a5cc04c3898342f4417f544604fd8dfa836110b205ba882a50f8ffb927a36f6fe57de160907f917c4dbde5e90c4c42e93fd76dd4485b1592909643abd2d1a3dbe1ede9f59afba10832abec98b0ed5b411b01c1b5c6d1b144608742d01e5ab51f2ab21148747dd30ae07bc3e1a3b4e9d2bdfef8abc4cb7ead009188a4b33b4b5948171d21832ada8cc8e0348c0cfd870c7daef6dcd79ff74610aa576d479b461fdf85dc636aa5722a6598564e8ac6439ac64561330c23907fb028093788bf15fcbdf449eaa7b9380fff2cebcc5a6acc23cec48a3419591f4c20386a9de89ec5d8fc18516bee4727688f8445ededa7caebaa0fbdf8935f1b2fe0813ac7e788f97a8e872193d4db4ec19ced75f74cf498cf87d00cb1a12140c9500489b19a4ec27a8dc3a8fc041a9cf59c430ae994d9ee730f4ecdd43959baf8e0a70023cc5de426904c2e0b3d0c58674e2736801a7a344623ce303e6e8042ded06e6092b240b9189e946e1d28aa19c02e31aa3f70236c83937bbbac9204443560c9037f598eeead125d3476862a6619b292de95db1677332b991b996f36f62f50b789f57cd38065c25afc9534769c0069ee4d8424decbde837b5f5563781113602bfb45f80fc8f501dfbbdd24d2448cbfafbed3ee9ecd04aa08b6299620177ca0c47c2529b89fb8ed6add5704e62acf2974a80511f94687850781a710b9bd2710a226b4bdd8fa87bb0e0ab67dfa73af1de7897dd47b0ea603d47430ac1ec8b7107b68e3f584f2756c3e6799d27c57261083602bc05573b785f7e072875168d6f00ea229fab5185839564c0444494a9f7e6ac5957a16842b509d6ae6d7753f0e50be3bcede698ebad9fadfc276877b2b021df919b7964d1d32755ace2499a850c0d22e5a6c18a21285788aeae7afce64c9734e50349fbc5e9b9dc796d3c7536e506d25ac6cbf2363b47d2ee00da877d1b207e97d5af25523989115049deb50e930bec1d38ee9cdbfe60c04af9489cdc1550e5d033a271e8c894f6b70b454aa36a0c91289608d3d8e324effce230c2fa11e5f74fcbbdf38530842cd75b5404558c07aa475d9079c3f5c2fa44b87b4eea63c148debcb13a2f1d786b046b4925d32b050e949393e904568dd0e7f97cb301ef497ac0f8b999a5525c8d0b806c33d2b90bf9412efd6187258bf2a3eae76f8ca5d477c0ce5ce3c71602e3a7501ab9276600feee187199cf3b5de125e3b067394ec3530f55b607440d49a7ea628ae6409b0845333cab6ab13e07e51b5a388703614768399424c919166836dfc611f8ed4d0e4741897df208fbe4049e8674688d8dfef4762e12f4c41ea3a337e1f05131b30c16f34a03d4a5faa882edef2ecfdfc6b184b8af12a4182abf4edbf9e6b371bc0130c3fa9ac3690af65faf5d78c39ac176f59c81d4ee2d2e87c6071c8167731c0d65a38041af41f92ed4399e4175fd4eaa3ddb7b53d8ee1bffdb279fd1d59e1d0f07ec6e63c4ebe0fa6b0ce28ff285ef00872b869d19e00dbdda52b49f1b655804eec84c738de9cc7b7967ef76fc1e5ce1aac617d6df94f435de04b71a80293b02233d574c4ab2cd0621a0ba200e992227e274c1e983c0910fe9a919b5fce0b103e96fe5abeaa04e2ecdd9d1cd2cc5ec8a47422c7beadfd6a951cfb27cee4cf106c88236dcb5cf2c885a6444fc350f0afd54897e7f93af7591bc2a19f45dd6970a399aeb18232f894ab8bc61478d3c2798bcc49acd005e7078c6cc63cf8a42fc0f57d987dcc42669db18dcd0497ce5d9b4f2687c4077a31140dd70c439f1edce0cd812dbeafc96feffc36d0587181338849e7f9e57ae58adfebef9049e7a1d7904a847aac69f33db9744cf311a1f487dafc02a4526784135b2213fcd861341b2063d88a6aa4a6e14f454808042a16aa014785a781f74a4d641e8948ef5387b0b014fada6b9ab71fb5319747e97e0440713a5bb2fc703a3ec892cf8cdb33c057303971e2a412fce8eadf5f037cacb3d3dfaa9bda984b16f41dd8235d542acb1a3025e3c1e3ef8f0aea805b29ef5cbcd1f770cdeb7627140fb75676aaa3192c11d037f50e781e00f4c9faf31b352970b2feed1c33218bdc47095ec97a203085cb80fbf1cb2fc07e0842dd4ead52cdceeb1de47d8136446b88662542451cf8a4d860132da06bc94770efb7d9033033fabf3e276dfb92434d04147ba65135c4596bd09820326a8ef4729d1561116ae65dca523e1302234e863376b2ecb757940427d04b861f17163728bcbde116506368b3b56f09bd85fdd6f51eea7da5dbe3d20f009898e61b623de90e167acddd298a13594bf151d345206d8979ee361ce3c91280de4cdcc2a4178acf5cb80f884499c068ea1a89f2f5bdb17ffc712f685d711250e0dd7b2d876ca3d0d56055b6c4bc40a1ecfa93b2a6e855ae17c2b2fda1a287407cb0bd0948d0116300a537ac1c7d9517ba02fbff59c3c631c59f54da697b9d70db01e50a0a5d0182d03cc5d0d77b63252553aafb5617a481690cff1e417c693091f55384cb1e719f7e2928433e735f80abea3c6806e6738ef2af7228f48037c07286bf4378b9ab9bdacf4c1bf055c2fe04aaa801b55b0b3e8fe12fbdedc0aea0e5e29f36fb16fee5f0640393af5b45420ccf4ab693e2555d88e278d735bd2370c2310cc8ec14aa57e3e5f2c86e0bd56a6f7f57c96ecb8a1a391071e8c9f36a600d86fd1cd6d9fb4a1dff363ab5acff05521a7f70f11d2e576980c0a93f4bcfd0f48c3f8db360325a18e391a5610daf26218a401a6731c6fb9baacd26aab3efb09287d6af54aa10ae3361f020858de66efea782d3de344538084f4856e02161d0c11f95a7df3a3227a4131da51be26097ba51679f334b0ee8938f988af9be4d806713ec9dc11678df0cb8deac6578855e95ff25862330bf38d5f166ed738069906b11cc52928aa9f4a1721aed3096d16d52a4b1a019a67f0c21e054d0fd8560b077120c683efe01a1c4982841c8c27c3b8b2295317e770efd58c5c751382901708b084aafb963ee3d2eea47d90a38f6becdd3c6d5f52b9d5a59be027f3ccc0aa078296df944f2035343c086c61c72ff889679cd699e2368a07c7053e16965abe07cd64043856fc94663aee6325a54def2a1404c7fb2349986d57d30df25d32ea020800b63a436b12f46de1fe7f628bee83bf804d0e7e08563e8dfe0d3fac6adc0c06d1fd9f474e47925ee6edc15a4abf7461ac863a545caaaaa27fb357a1bb6b0a611adcf728fe02b1e85f932abd7a18582dc96d57b6e6651be7c90067cfcc540a4d0d0dd6b053530640c901cc812c7618532cf65bd93e6870a643f2d838a0140b6d323533175de3f8ad5fe5e7bea282172b613b1e452b9d59ab0ebe49f6e76405f5c1018de4f18ae64cf0e6f7132e91e76f809d4b80c25eb9e113a77135cf1a00e22dedc495ed82fbdb48dfdc5b345fefd765da95c3320570c0c34031b771a501e9b9105e78d3e8a19e3eb27032b26ac18faa474bd95bff7aac372047df802507da397fa56d4fa921c536dfef8fbe5d4f45dbc9a49771249086b638a63f723f00b6c99fbef8cc066858b07a5a2c5f8c521fb76e608d42f5bec36b9201af1f4a0acb764a8f608c3dcaa26883824754c97535e959927c5934ae0a690ff1619d78007fe66aad7529b2fe0eb855d66bf511a501800616200ebf192a0743ad5c6d3b0a157b4e27188cdd9712b651ba97edc94fa6ad70914a589bc2683fc9f488af820d5de1e33709d209d523784da440f357d92135393fd1cc32a2af2eafe1f6a7a0044f87dc2b0efc2b5193315e68eb81d597af702191a9b49c758c1738775d7de20f907137c13d91d10d6088dee91a1cbe2dba5932bcb30ae8d3827a06e8463b4207b5646811c0fdb3a8b20b02af28d28a18d5b12fc711cffcf50ac6e254fb0f7d009359200de982e31be3f766835b3cf43dc4c47b4f0be6bbc64294a4ee418ee40de1f98448e04cf13cf193bbbe45c21526ea6849ed3a78531489364bf4f8bafc0a70256f8632008bf7f409375755b819ba9a4c5833b10f1b01bfc817387050340c2b7fa941456d74f032c29c2688b9bab90dffbe5ebd33f889110f2a74168695076b07e00607b910ece4ad97691f0e6a4b3b8b6adff0fbdb14bc467daccb3bf90d34f6d9f47acfaa99a28fcaddfdf587bbe3be268c3b47f281e3fbb6b86402a20309dcbb669ab6b939dbc7e02d57f8c0f5015261aff3517ade2978ac8853d10a0a91769a5cc20c64086a6dead4dccb330e3a5a94e7bc55156ba4f7aaa6ec3c0b037688f7256b664d335d86d13968a62b8821fb0033d68c98c41e29a08f608dd40d2b35c7858fc8c9e91e356af041aa91261fb774982e9802b076534bf6885d8e0aa6135c2c7b46107941595580eaa2f4c9ee9789b9395b3331a5158df4d714ec0aa456ba7c27318e798a8c75385d6a2aa1deac41543cc3cab0f55aa81dbddb130cded1e0bb5528feaf4dddbb8f08dba9ba5a374d779b03e5f6f526c3d6bc95c608ec938d2bb12cc267ecc9c7df88652ae8dbeacbf4468f2c31f52dda5ff0b44b04390cb5e4516c08c9751a2af38c66f3c28574231157f7080d20256147d478e90caeb23d226eb2f94f5ccb4d13f1efd01a5bc81c6db1fd5b52f6a65d9878f5c4088a385e71b812137611cc8208e977bbd263f74e37172d27db3ef1531145af34064c3efaf01a3e5cfaa3886a4fa1ab744c5c914d641ebd12a522f1a1bef4b73a0cdeb131af234e6b829a1f4b6f3ac4605cf6763267fb052b4c9e45bee229b4780ace00a3691375ba578186068d28b9ecb884d13820b14bdc5a4a0357bd4df0ba09ee43f09383e50e0291b955e2fa5dc0f5368c686c6dd0a02c084ad03603bbd3090a26264238d46d7ae650f6aeb355c7cc8dd567c05bfef798e0696ea2d308790c375813154c0a01371b922d5184bb982b51141ec65832abc640a45ea035751b03d90df73fcd1feaf5a24fd448cabbe7fe5a3cf412794e57201190dcdaa1a6950f820707d9b77cbe9194b07a81bed7b5488b252a5072e524ffbb4b6d88a333fd058d25524fbd5db55c844aa667fe9103d1fa00358db2c7eaff721fa0ee6718f80ccc64bad3252aa71c5bab323abb013dd00527549cbdc7c88ef4ee7a61be728d0eb8b97d42ec7fc98a8417f5908a4b6d1b46123dd8025bcbb795f948860eb92e488030014c794d9fedbcb37af2ff367fda24adb55f87f4005a261e3fe1624c23d48c762fcb522f6ed3325ee35500397ca34ceebb9b4055f97e0fe22c26f08ff12ad1c842501c06efb9c1fdcf93010ab03d57e91b62f401fdfae5806a3d5d3ca871b4df6d76ae7cb7d7930dc106470285ae70f4f82df5bd490a3a57912a25fc41e2921e33eecb863fc31a3bb2bf3ae344b221b097dfa1128765e1cdd69a2222278099435cf8a7025df6feccd18eb77f7757d54119a297c60d4232e2c4fc79094b2a35b7ef3b49bb8c7daf3973de566014f9a133cfd042663f6694f18e59a6d02b53b7ba375e0ae7137693c95b9cb31c78aaa3395ba2218014b3a7d7384e364506e61ce18b4746a24ce32fa833eee9dad6409ed1f759e0c321e59030d41be00f56b8788da170a6002bbef81efa5a0f4cc05a06fe57de0237147f317c1f8cf6d0a9eb7c7d785418bbbc890208071c30feff7086300383f9c2a5bd6ed02945c59f7f09bca1281ad81fcf4115ad15558af9a923a0a765401b8b405b37a7f9e1b432d15d2cb45ac554ed655c61f738b04d9fc6590abed04e46df6ccf3cd39c70d3c86bec2e04026d73bbb34c8bf6ba506ec04f7ff7813f60dde267a9f51ef2cd73429b0ab9bef6bdd259ca3a0875037e887322fe3547adf1f9c7ec9c785d7461c0dbf5e6e3e0e56242b741adde8e855c67c69beba61bb6d703d8d9b804e082336e473270fcdbc0b328881b61ab0a9be64c0f92fc2e2d6ed4b52694aee4d39e0b43ae74de1429b0ca679b7244973025baaf566941c13218915501b55a5096ab2732751a333188d4aab6e7bd1935e5426e968b94d61762457f3a469cd05053c381047cf6904ce6beca7e3e0f8bf1a1873991fbe89c5e9ef03765ada136118eba5a95c8e5558d783e8013dc8510f1c5ba0103aacc8262e2f164ab7acb88346067f6731947524666ff54c726abb146427db2eebd658878823be7ccada77a3b602b9691a3b023831b708148bdb94351219e76d64eefcedc0fbaec63b1291ff1d4cd6400035b8ccbfd676553266dd8a2c1f38774441273bc8cbe387e15366ce2486985ed2015c278218606ac8dbfa2597947a97acda8d8c340bbee06adb6c79ceca8d807489450d6db033e9c434838e5ba80d420a5167466b3d6a0d2f74c9034f36fd28204c0379e91d98c894859988a81ad3ed312f969e13936cc267e834585a972298e6bd48345da633231f45f1fccfd8d9abaf13479d432a0b6998878dd26308d86ba262f5b4ea507bf3e85cc6cf708c546d21cea21f90f4542801ac004b406a09199ae9a58299be3b662cc21206270978db5d201373d0c074607bd63dfac803e07f624d7b19186a2ccf3a1d39660a0d02375cc90c655f17a82688eab73f0dc04782b797e3b87a6f8ae5eafc5fc69bfda69f8602f1c1fbc10d4793998b6fdb1fcac8d5a4596c8fe39a6aa0d9ee11a944bf01e825535226110aed52d8d2b224304fdc2e8283355e8425a978f66e7f124c36f564d5c8e3101ff59ceee19f6052206cb6cdb33eb52157eec39e0baaf887629f8853d255757d4c3367388430f641c9ca2aafb35edd847ccc7a967439465a9f71050cb4310f87677823f432ef54cfc0610988a9d2460454d6d21357d05f6e74239ae0573e80785a76d593ba630007d8982701867f24ae917411e650978f6c0eb49f2de65e510167143de48a132430fd757375eb7e713f716864770d8bb0fdb1326c8839ba45bcd1efbc346f879af028174f84ea70dbef097137282086e872d33eceacfae92254531f1ae9143b3b6c646dee88e67d700b5e6c82ce8fdb740665d77983fd664153df40461be914122c0398925e57f19d6b2c1d41193b3318fac1458c2d856ee8ffb0b920b4e4c239bdfd7b250862dec014da90b6985cb711e2a039d77848b8e140bbd30c22cb717460f223ed6ac84b97c3d99eb2a5bad7658aeb35a70080a7c91b95f0b649ce6f69d0e031bbc5ae455736aa3d3b35fdf41c2db1cf3646d70db380e4428ff97be064f2d1eb8d76cb4d7ecab5a7da0881d42a9df5650827f21d09e80ab18203a0bcc8ee72b97a3baa9b582748769374e538f24344c0b27a627c046ccbbb4d4d65e5607089dccd77595f1f190f3dadf930a78f6fc85fcb6a823561fea66394b2fce62610f0197664cc6a4e81180342df347d36ad48460c9c16a75fba95d0f45773e87d514da9c635cda60c746260af1c099796513e3317248ddf69ef69e23025083ce8d5fde1231cec7c41f5b03c76fce4a0a05d570ce013da78b8b6cd2345ac1d17748392b900158e094155a6787a33a4d6bc33c4ed2a72afa8038a4d050324a22c924b1fb5243e121dd7f6383180fcfea0fb3e55288efcae3e07c56cbeb1182bf2a63ba53897295ab300df3ac0272d666f9cdab504a27b71ea0aa216ea31c10b349b2659691e570dcbf2abb645f78a7913d5e1ae3b1742d1c1ce9575ee8c232bdb1fa48ea9e6ae409dca660d988727de5118d8099ef2731b92dcb2b2b5182d4756787a6477f740c0b95ee9a8a956c10911c94bbf82a3cafdd10843a84715ca1c110c0cf762117ed38453729578dc9fb71f1f49418c0c00f23c85ead07e44f7d695b1d16cb7a2b6c8213995080f649fb382314621c27247cb692c17f9ce1c4ee3c4c3c01910707aa95747866039117b542fcfb12b3420a89e7969f0a5dbfd0fa01109150364f25e2244c78a12a3fb6f90eaae7ba897c04017fc9ceafd9293472b6dd456a5fce7da72d38e54921b7499dfb26c85f9168468153e5f3b134587ff7e46e42d049fed1c6796c9774887c523b12f3801a951c39df452d7e38c39077ea8e9b03428d5c54e79f4284a5e4771dfe419bae9cd8238c3c5dd588ab57ee106eda5f39327f07f2f5bf0222f30164f7e7860dbafef914e7b6377d81c01f8f49fa7dfdedd19d19f0077803c43fe9631aaf10ccd8634c46bde6382b89411c906e7321cb8503028b98400909f1917df0353a7a40924ef038e528aac9cd330cc3663dda05d12cdd00306d350545ac159fa68526693e721c6a14a512a8684edd2bd3d2a03c4a8e282cc2d1ac00bf733528e0230f6817d158860d5812a7276b44f75ad2915215d478972a705e09d4ff6a5e367576bafc1c788d1d8d38e714b82fb0f8195b839acd6aeff96d6e0c9b35d0238ccf229db02d85c6689c03715ac0db13defb1c456599feecc0a9b70e09142e43ee959f32ae31049ab04a316403c214e4381bc08696dcede100f59f0cc1aeba14149b269d4e5476e3a8566545401bf0985421e5f55b9bc18911f69f0a8036fd364dbe6eff2d68e8c403a9916aa730fb1012fba88a975851e386c78109b8744d833db1cbb5468dae1914c1274619fec797e040008a931e534bb694820ecee77ec683e3cea3064a8eb436a3fc1e958f270c010d8a54504c23185b478c019f6db80ed99f2abc240e05710b88381fd2ee696bce8fc80aa91ce1ca17ca0f04" 80 tx_data_blob, _ := hex.DecodeString(tx_data_hex) 81 82 var tx Transaction 83 84 err := tx.DeserializeHeader(tx_data_blob) 85 86 if err != nil { 87 t.Error("DeserializeHeader transaction from blockheight 1302238 beb76a82ea17400cd6d7f595f70e1667d2018ed8f5a78d1ce07484222618c3cd\n") 88 return 89 } 90 91 // verify prefix hash 92 calculated_prefix_hash := tx.GetPrefixHash() 93 94 if hex.EncodeToString([]byte(calculated_prefix_hash[:])) != "1bbfda600fa6affc80dae05b1124bf05ed0e20890aa42601441dbe0f6fa81f4b" { 95 t.Error("Prefix hash mismatched") 96 } 97 98 // be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843 99 calculated_hash := tx.GetHash() 100 101 if hex.EncodeToString([]byte(calculated_hash[:])) != "be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843" { 102 t.Error("transaction hash mismatched") 103 } 104 105 // now serialize once again 106 // 107 serialised := tx.SerializeHeader() 108 _ = serialised 109 110 tx.Clear() 111 112 err = tx.DeserializeHeader(serialised) 113 114 /*if err != nil { 115 t.Error("DeserializeHeader transaction from blockheight 1302238 beb76a82ea17400cd6d7f595f70e1667d2018ed8f5a78d1ce07484222618c3cd\n") 116 return 117 }*/ 118 119 if hex.EncodeToString(serialised) != hex.EncodeToString(tx.SerializeHeader()) { 120 121 t.Logf("serialized %s\n", hex.EncodeToString(serialised)) 122 t.Logf("reserialized %s\n", hex.EncodeToString(tx.SerializeHeader())) 123 t.Error("Serialize TX Failed") 124 } 125 126 if tx.IsCoinbase() == true { 127 t.Errorf("be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843 is NOT Coinbase\n") 128 } 129 130 } 131 132 // test taken from derod project block 72 txid 2c4738d3856e8e3e8f9fc4818a9197d4911af3010e067ec56d08c264627cb547 133 //transaction_test.go 134 func Test_Transaction_Deserialisation_Height_72_second(t *testing.T) { 135 136 // transaction from height 72 txid 2c4738d3856e8e3e8f9fc4818a9197d4911af3010e067ec56d08c264627cb547 137 138 tx_data_hex := "0200010200050401030301b27b6cf2e0dcfc35f2767608cace34e59b1d507d3ef6c5ad7142a1c3aad0d860020002b9ca87703ad2b72bd3bad724a42d3569ac107c6fa8cae194fbcd560cabc1abd50002d76035fd955ef8b10513f95d11fd7a579bcc1db343be0ddd67d656c505061d0a2101cbd8cdb9b2bd3cc79b720a124c16c5eae988ff2248681dd1db25dc146e8923760180a088b78303b918962e3d710e3fa38942f1b7973d9e5038dd634a1b0013a795ad362dff4c07c8aab3a0983d712894adc5a5ab95e20d27c0a4176b3dfff40abf5914db35ad0372a81534185e2e277d6e97edb519aff7bf15ad5787a69645dbf852243492bc0d23a8c131e046440fe14405725b8c23a4e1b0eaec7599b0e4f95c491f469a7c05dcad515f5c209469702fbd6e5ce3f31a19cf8e357105ab65b041a6b5659fd2e7f43a5705a5c430faa8919a9cac7916a3587b95f90b286fb613c83571164ec345e3ac3fefeba9cb534eb200f1cd414e1ba08b42d572f5683093675c7c7393c30578c243f58df05209153d60ac583c1fec19d34de1c9ac50fc2508ef3a0c101603fe6689822ed4ea38ae22b8ab49b5ce1c1f5f695d79e4fdcd0545b8be5ead280ae4956b38254385d155662b146156ea716003da11facc8069b5b80306394e480c03333d6d8c81464547a3f1554c3b14bc4cab044594ca8f154065f02fd2b91e0d5d1fbd231cad765476bdd145732ebef719000a4547fde18372a06997237a53098f948d034477d034cbb037ce9861dd62994a4c9280e3f6865a9bfb999b2f600e5c2b59b6b576835014b89d095630e2e0bcb2533da55d94459db12e3a6539d70f1159c56d03d32eb7bb692f6ec469987266bd6e700a644b70060b1df9ba1ab405ba58abdcd95d5df5dce80e12c2fb15dbc5fc48d661da51663fec085d4597dd071a17c579d217e1af98b14d5e94ed65255f4ab86b6735749e3e4ff458d930720297ab3d5361646c616999e9d9895b2ecba08802f3df046c81a614483660d4430ff336be4bd999056102feeba4af5caf69e0eb9c8c95ddbba4b77aa1715c10da0e2fdbce23691327c0cf531aa0acbc3c80ca84a242c56200230bb20f39f226650b398515af0eae95bcfa0f5833b45692e00182dec2e4546f49c4e3928273f2790e30da038a905bd4ee0eefc38bb761aa7281ef13b6e664bd9b333c739ed9aeed0783e6987bac3c0f3de463de521ab6f88a50dbbb368f3ce13d463c2f39a674c605f834c4ebb9195626d17c14ed8822abd4946908ebeb097f8f90e4482d12895e0a7308eeddc1efb989d14188abe164ce80a742f1c23621e0f881676e0508a6d10cbf4f40c71c41d47b63705738609fcc6a561899a3a295f91178f61c8f23bc09022fe425b5db9e7191220594cb711b68ec383afdd2073779069ba9d23fe0b53d041a4c95bbed2aedfbc7793189c0f9e1f93d8addc088e9f9c964f8804e383c020513c8ef12e99b90f73b5dbdb6ea82a50e93d74e8e50a07bda15a8fbcdf76e9e09f996d276c9611939cac7b5a3a13c3edec0241b9fcb2c3600146c056519f5ac0473da3a9a4cff0c744b30e18883396822daaf70307c0ee818863f3835a6d9fd0fb6c4cdf98895267a407ae3042d5e422389cac50723a2565724d4de7047d1d703b469bad46b46f9e6ce8e27ef33b00b24570c3560e1443a15d62124b391509f02e85e9c8ebae05ee533c0922b3bd6cc00ccea4167ab7370f615501976553c350b6f7b21f592782476bdf87acab34d53365aa76597ef8db3e4cb2022fa06b75f010ad2d259d139e592bbd52cbe4a9aeb3697c3a5ef726bb86d550c043d2046ef01429ff761fe175632253b7752f2106954c1cb569e513b36452f4d91a93c750001d8e75312c2be5fed07d2dbce8bdf4daa9d5fc161135e83ca61d828565aa3310c4b09004486285c738f7ebc55361f97a05e608e99a2e771c51f559230d264580ee61d8bc4e96ed132ce187be8f069aacc7d72ee216cf311184a1e08daf9a18c0bb07db1ecf5dacdd266ccd4767e2b8ef6c6ad066db45af7d68af29a54ba50cf076ecf21c2e24eef9d27ea635ce0260769c7c76c386a98f2fccda1f52e8495870f2b28149b9f15ef41111c4db005fda31e46625914bab04c5bf293ec0154530f04002bb7fdebc041bcce84ceceb22ee2b3ec7959a32cb6dea38c274b5f6c140009c18f67dbc949f9a4c10b1b3c709335d3991f55bf78613dbb85a9366d52ff7b03468ecc848d2bf68ea3840f40c6621c72c3eda4fdb44261b08bdd8a1ad281e309ca9459d6cb2348ba736b20e55f1c6608c5de6a29523a9575398c9d2bad213304eadc57428c5435cbe8926df2481a31bf0301c69dea0064c18e1ff958e398ec0317d03723cf698698c06403e1f93dea759d801a30f95728db04d3e1a1383feb027da8683e4e5708a5290ff14235d9fda14e9f2c0cae514d058224fd02cdced3067ba2df876ea5f6ba6d2523a53fe33290500c954845fb517173d5ed3b1c86d00fa6066e7dbb523e3c5e61561a003ea95609537eca80b3612ae21c0fe21787f6067a82f20e965062e21403d43d9f4f3dc20a53ed86a72887eb103187ae1ad24504874e565fee47b6679252f35e63fa7ae2521c832f5410fa07ca47bf4a3233ce013ef73d29366c7882a7514d8bb1b6382c587bbd9d4a769fa00f4921afcad9da04d67f8d6795591614b3321a3a45b58c0938102e96ed1ca4c1bbadfb49db33e700b67e84b16e69b6ac24dd5491ef58532abbd513579019df1f9edab7c656686d0df0157db9526307cd81fbfe79a1d3372f4d05946449c88a2a68dfb80522eccb0d661fe7fdd0773fdc67c65839ddb77ff9b3890a52f94e0536620ac3eedfa7940b88d224e7caecbdbc12077d19516f7f3d47625c093d84778a9aff02a8ed4ebe0ad9551ac8f4d59c93bcbd4f5e02686b47f14b48ea8cf15ca4368a946049b6a40b75f28dc053ee8f36a03a51a119c45994b4d7f03422ee437567b1d8269de62104250e6aa8659c6edbf794f60e19c983349ed92edda1fc164f6bd325ba97ab3b02bf83968b74b7c6a9c171ee7798713ccb578ddd7aea14f9215490d98d75ccda03dbd2a38666d7cc8792c80afa931fee64785e1a3156617724f8d7e934fa56c20cc8e9e8965c847794a31b1e5774ac547766ae8603d08022e07bc66f5336139e01eb1b92685611bfd1b907d5d8a72bee15c8f12c2dd685282662860df331a89303c1e2125eeaa08e5bd09ce42b604f6375df5a987080457d0b2d111a82482b030efd2967f096f3e307d114361cf5d88af7d151d573c9800172b7481a95465aff0df8858fa3d4f8c9fc089f90a5766662337e6ab89c37e596917fd92bee8edf430ac71519138f633492c6325aaba4b240cc347479fa26c77138b07fa82b00bc12063710a21290ed2d6d60d9accba8ffc1e4f501c98fb5b4355bc91b0e8788c92f09ce59a51153e0772704212c3d0dc6ec01b9296926e1254acbbff73f25d096e20cd4c86621e609e04df77078e5939aa979be5f2e571b3b422113ddf3b7f11ea704ad61bc954526dfc9bd0ecc339d83446088bebefe1e6dec08709c7dcbd07846069d448776291e202ee003fb51b0c765b10ba7a3c022fce045bd0c04163636b602e06eab18acd86a108bdfd42a8c5ae3314f7726ef35d12d54054402eb32c7740aac15f3a1fd09aaecc13aae4095b03b6fc35a17a62cde59916f07aa5b2abb190d8631490179f472fae6b8ea4b229fe8ed6a8143b5054ccc7b36b7fa0ec6c0110fe064d130b183e70a3ca36927744b8e14dea1d89778601579fb76076b157e2b0515ab0da39da3b2e33d9a153d6006ee8da09b7628066d0f7e1f9207fcf6b68d03085987c906a67c4949e6104444bce8db96481523bb5182e65cefae237c08a80c68fdbba091bbabb038342b330cbfaa62dd3aaac2f39134029c78b368235ff209eb7056b022dc5e6f0bb0e344c310554fd01043a3a0092b446b3dea67f7bde90f6bdfc86a9dd20a83bd0c13f297476b0957fa7b2020bbf258cf0f15ec4af35b0b7fc884c53e1d81e742c73194ee68c47e7d2a17dbcde1599f10cceb75b48f9b0f72fc84d9f359784d69bb0d4f8ff745e6d14421c5b867b69b7468c899cf8e3208673942dcf195da4c7674b4603023cd4e9740fc949a535329144a509084754a09a7d7f93f3930110ea12b1e59936832671ed9c338ed7b12537280db0e3552690625759f2def660f20c30d3b62bca5d10b5a85c2d3a323c428b264f3fca5cda2007f9cc73babbb4113417f195b964e4215e7d06c9f5f2b2984452f5cd0562a660d53b47804be205be45132673a0e87e9b358d188a4bb13f308dfd48e7d3a19cc00cdaee3472b64270d61509025f63d011fea544e4bd406713b3a96189d51926e0a0d4978cac42ac91e75f00af0c556f85c578e9c8cc130a720c8bb691047d4ed0b86a4600f19eeeab92b6c06e3a75f452ce3239f6008db5a20fe95231c9063920d5153d78ba0d47fdfa7b79f6f726bb2161d36bc85136a5f4f4d82b1e6c083b10fded692fe72de12c4984236d1b25bda589712b8d3c66edaed40e94469fdbe700013f834241a6cfb42eaf841d6c4db5b8349b1fd2e56e36b30ea16c56bc5f9bf0e72ffbc2726568acb459f285ce90eca77e2f74bd88cbc6c8d74ed76ea35031d02fd1f129c63e7b2c0b2cfaa223c07321759658ae50360e3e775f0fe71fbeaf405b2a0f552b73d6790869f3436c2f3c736c6a67e6c6dd5a2761e83b88b3399bd02a8103b4b3656b947f2b713dfc453290f0c9bb4d2064e7f51ccf14169d80c0a064f22df85734e06e3055b00d2034e5a5e2cbacb0dc2cc663dad72a638581ea1090ed7a972cfd74e693887a43ba97bdd895109387f530ccf78e1aa4a19a110150f79710c93fe6e630732a6ebc88e0592f042a1bd56f4d8f6ce39e6c1fb2b348e087434bfa3778d205f3058f621711a41681962cdc9d0afe3973714ad80df48960968859d1f47f2366f3d7fb2b62f89715f603475d84e70ee690485dbe579b6300929711cbc966646400f2e6cfc62e370b614427648349634d0bd2ee6149637d3072d2b67859ace2ac967008fd5265aa2b1487a2057ece59e31482ea7b8df517404c2c92f59f55013b79b111b6d193855e5d4eb10e23b816b95644a1e61c7bcc00fda604315d9b884472f051ac13aa7546dfc784b72d7be2dadbdfe7900acc884057becad608b1d379e920f129c5f3a40af6a9d032fc45746f95236dd294efa0c0206fef604277f428f91e15f729a4b073ce12253f9d71c8b528c650c68dab076064b7ec6b0bda314dcb5602b6e892b5f31f032626ea6daebcf00e3f065153afd0c9c107cb4575d14cd35a72dbe72926e1b1986f528344b48b6c6bf817ae0bc9e0fdd9609461fc8cd76c972f028fb462db6c45bceb305812c54788f78602e5e1c01d4b11d6a580e93fab23495e9196eab78e4ff6ebf503e2d9414e8b8e1e5467d02fc1485ff7770e55656b9dcad13e91977379d670246e930d2d1661ec6ef31fd07479c8a9e42533c3328fc9e06bb09daf0e4383ed01394f4ce141c348998f8ec0e232848dd1612e5a8e29c1e50388a52fed2dc454d69ee3feae06d5ed44260530d8b918cc3a38ab589c58f7d855b3b93e5308491b56c6db8459ef7689f6b65d4084948a2c640b270a532d9b9310f600f0e5344d036a62d8f8d070f2c2a581b9a0414ddebe3a2d7afca247a7620ceb4970ec165ea7f0f4b65921ad5b72fdd0e7309b0c5bbc5409047e4a69214c213f6de201fd9705910c271e00d68731e28452604d40e5745098f04af5101d4fcb82351d763b2932807a07910afe31e09f6a199041305c50e8a5ff91464a19da5c06595e4a9398f692cb63dd920cde0a561f618067fa96a1c8aa1bb12012648fda97b16d1f6afe278af426458422c8198ac701f0212b1d43e6fb11c8ada3b3f79c16a6121c9d6fc51125223fc1c2929dea48dc60331d265346fadd531c2a1f7e78fae8c090e8b2353b0f79b58b1974428f7ba2908c6ed42728cfd69ef902800104eae20745161c3b1d07e2313ce4f3f281093c60ff0a47bf7f2006666bbdb4ce7a6e620a546ea61cebef87828d5dfa167b5e509013b9bef499c3e926ca9c0c961920639caa0e630a3b24c8a524f3e64289778030d425399eaba73c14af22f91017982fdfbe0dc118ade0257dfcd4e40643fd9a702c4b72a3044df7b9d0a8cd098e443b62cb6dc7926064a1375c464b372102f050c873d95d1de2d084d97a8ac1fe73f4530caba213c790e3170a7c50b2a460c0602c4a32a44ca512ca7f3edb4f808118cd0af067741985d59dc693ed15383add649552c8c4737e649bc357445a0ac85e38433cac3e9cc45046108d008c04cc3b83b55d04c6434c011f6133d71e109fd088081368f694831e0687530ab7112d0287f20ddf2df27f5646e0cdc2f7a7bfb5d65202dc53a3d735856c895a1d340b64f22638ae26368f32040d627402784993690e829c763ab4d4896f1159f5b2c7d4ffc5461952c57eeeac0d54170000f1eee31452a5c356a32e90af93211322c1c6a617ec29da1d685edbe5322bea3d041c2d8237e47ae977c48199a06e601dee206ec9fb45ea5ea69b6c29deb597e8e848f35d4096e84d0e3cedbb6fce1ad6894b5866acb5eb6bef69833b9bd4328f36becdd1ae503305889f40bf1af3d06eac1517b6ff7ec977b1831efed15da93500e1852eeefc1c99ea82e74f26c5dfb109304738bfe8b667e9ead0df23d1c3536d0afe1b22a907dfd4099aa071ca78a35cdcf0bb61973c8050aa6c1d668207a4c7439ac71110673bc4d2a4f79e87e45b287cf7a156430e07c4669947d47ba861ae2bc77942c25304947021a3efbc120062d9f4466dc59acadab8542c2aa3784d6b92511caa3a16318220beb872d44193e2fd2b8afa174700aba3f9842e621cbd955d4e33c05b2b9a0693fd2dee7c6ff832734926fdac894e6e7fad4602063f502748863f50110a4577d850fc5146b5292bfb1ec4444d51ae9d8f83b7029cf31b763874b3784c4f7a5cc3d40b05223cae404a854cb5cbb4061678c951b20b786709ab5b36add00f2e0bbe6c37c0fa197c805ff50961d7c9a3c30d994b4a489d82dfcf167c7613c57b3197aaf3a3629b4e7fd4759f7d74ce715c908b1dfaf3c13afd7f767b2aa4650bf5cb463ef8b732686a84f14e78e320d77639d72630bf7a7d5c2bba545033b7dfcca089e486977068a6c80017ecf71cb223d8b6eae99b2f857cb600a02fc1487366813199307bcac1ddcace3da6d788ffd94db9a9d674828ae0b900425020531f0bf7ddb470e75568cee0e54f5b875cbadac758f248d07bc98a3a6361c0da6fe4dae978467e59cabf672d5aa56c7005d4b1bf6049069197d4214bea2911966add2467b746569c17e909e2b93f574f1c03f1b2d2ac595cc88e2f839b852e07b53d712b9a028b7405d2dff33adf172be9ad6853c3244b985a49793657d2b4ecf97f5b7aa7c2621379f02f8e7fc2e72dd6df35881f3b8864b06ac00077ff8caf90998858025059398fb9985c9c63632249d006c4aeeae760b7c040174a35334cdef63e8913534091f0f1bdb9cfcbfd7d634e8cc87eb2932ba23de5dd611b538e33b1883bcbfa00b4c228736a632d5eea04fd519daa4be4adb45e17675def3d5dffca0bba0ca8d1293e42087b1c75c90c36f288244a6c99c5d42cb5c9bd02b6999e01321a3ddc2f30e6c2827a63232a5e684e7e2d15c2ed821317f586c89774031a975dd6dc2be0ffdab2476b8e39a087b703cf7013c59a8a9e49a08527622d55336d0442a2fc76fd199be6886aed11e34f55df9abe5e72177bb74bca8d8200c5ad800b7e485c2cf04ff513974f7a67d9df7b79dd2d6a0bb72dcd7d449e7c8a4415a5b18f6a071cccbbe084b97bc5413b9e3b1e629d083859ef560d18dd4a1731f4ba26808a6fc7b6920ce128068181e22566260de418a93d7fc144e5366bd640fcb08b47286a20525fc17a50a1d4f8f01cf31e1ac5930f233e11f16f7cfc0d75c22a26e1b928e1f690677a820990f0d8f0cb725fe6f142179caa96c59c1f7bc7ff92c975a5cba9fb24d388a41aedebe54408b221e9fde3beffc35a65117ce070fb59dad7746bbf6410c990dea68c20697569a770cb11869b15bb0c46bd4c4fde912d54e84f483ac4e13e238c05005ab69e308dcb4e6f5006041b86ea63bc21281f465b3576d5cf62155ade0d535e099dadaf10570b5f2b0389223310bba2a6bc021bbf2e4c741df1644a2405f39e89dc74877738bc74c1216e23f26a4db66d490f67e5cdd9761e0ddb5b47b199ff8c7e4373e1a21502852bbed7de6f06eb3a4bb28f517638d1409d461b7a9ba5dc3e5939e8d828b11f0ee5cb23fae7d06d19e88a7f8584d557a4b0326197ae51ee4a96bcecd79a1151627e53907a77766bda2727ad3fc280049ef5537fbbe96d951a7d34e1f61e9b00942a79ec4645d2f47edb95b1e4182e57a3fd0631118dc78fe901e37604c0042b6bcf23c503cb6867e377230f2790fb38e42bae1e397b655ff56dbaf7b1571ebc1d77a9cc960a87a5ad0bbfc77e7629290d3d4e7c6183296d342a18337353495979ad55cd7d349896fd7e411f147521034dcfde8d0ffec3bd16c31e887909a6a293d74fb3b9e6ade460416dd18e3d55e16d7882323bcdc5b49c835cc7cb50f993bac540c89d96aca7d5ea94dd107de5125e7f9162a9aab9c84c39eb8430952eb971510dc58e81ad25ccacac867a69db300e8098a54fa7b4dbf41a7f251d8263999d29c6a16e4f3fc728db5480db9e10f9ac7109156de29517737f8bdf4af7cc572ee8b9f6994815860af6cafc6c3b67d340513b85d832eab12c13cc50322f687553e945ed00d26f97411b5dc718659f8b8e6b57b93a4a94e51c9b84ba9548047e28999864f9fe8d5c618aefdb06c0e6ccb3db46e17f95d58f45c8db3e26ebec1d73cc6cc4e3e5f177321807896a2cbb98ad30dc16780b1c5de57f7983c869aabe4b46ee3ee6ba03fb72851da3a0e21e1cd1b15f9a09c84f886f5d7468d264b73a716985d82cbda02177562b0256e06f8c1f00310311429ac36d0ec0cfd9e36e929ac1523d79172a192bdca6cb18470f9258d491fde622521bf8975e49123447bc61659bb1433be06de61f02df57a063a40c3e457b62884c02df073e59fd02e2b44d9e33eaeb994c7b626389334577fde5ab351eee0148900c489ffcf80d72c7173ae76747f77b53f9d145b57eea48da0a69572f01fc38c02cbfd13df7a1697e0355b01fe431d090382569401c4a1830451ac205afe2d160a7bdbe44bcbc5161525453e95d4eae803706677a52f0ca98f58f400bb6c23de0aa61bfc621442d39c44178c848a1329e062a95518551ede4b2a29f2275f8eef0e453b1496fe920a2cf8a473fc11e1b83151ab5da3d98ed4f78196276ee4c27f06239c31e080d5efd0a5feebd3543a650075e764fc317ad207e46ac1580841c90744ab4f05958708589f5ead9e13279c87786603ced9091ffef53d038b25480b0061843f35a5305d1bd6b878c475206ba922993859df33da1fe4fef10cfb96cd0083f6b370825d46c691e179373ac82e77c8d888eee9ae96a4a4898a377c57750da0a5b4d3b3763e1a9c588e6de5965aa7f61df595f301e5f993f9a8fa6ecaa70dff59f6f78822a41b276d7f55c6a08558cd5c6d146b2dc64457c7bc1a2a1e360525a55c31c828c031f0f8eb25b6212e2c589abd1ef88b6b39f56387c80a138708040e0bb75781ddf8dced1e3ba2fb1f8dfe49c68d7f81f9a84fdc54c8d95cc406f93f0e772494900d79c52be3cd04fb5022bd5fe467da594ce6450c77cf9b850237b996f03c4568e28422526d30a612d7bdc02864c8134b38d36993295c129403663a763a8e2e540d6eab3dafe641f0a184d3b23c2e6276ebaefc4e2773fedd029a3815b8d6a1129d4f46c74d772d9c279caa4289f53469e34a49a473f6542407f9e0ed855140ee74cd5758d3ae47cc7d713026650c06a11634e0c71415d535063162faa5532b8e23debe40853ee95d08b9f3a855594253a4e1deebcb3b0606005978d410e825b60b19e57c20bbcfb6d0983a49e372afa9d9e713cbd04912850667d75dc98ffee297a102dd5e5dfbc5797fbb8ca078f6a350b16b3b8f6044970b1462b5321e89f97760cd7d98e2e3531df99f460969f9b66e3f10486ff19f6e08d6793e5c0d182a1ac60460ec50b007b79e2c13290f51baef5048c7e081af620f12819aa103bbd1daa7636bfeb494aa6de5d2db1e50115306c9d6aafd8cd5c500b59408c23b5c75b28a5c2148af9f23cb94e0be1d02588bb05346154544a1ed0a5d7ede9fad303a03a8d977cfa25d194d1843d1ad5a33b7efd9d52def5360f300bbea37904625de0b26d918e16e2ad1c8837776190990fba72717fd357b627a04a2fbceff9453d81ee533d45820d1b9ff3b8ed7b0fd23659c69fe901eb7c4d20b849a2c31a937fe6978cf0389a723669814dfd320f33f510b977c07accb0f6a049e29cff30a9cf9684fbc37050463c062b914ac2e390241ec827b05f7d9e28d02924d679292b5b53ffa43cb8f4fc33b05eaf981917c959ffb3d76b4028fa11a0479faf4cb330a46722844a6e36dea14fa4e5229a9ae01f04380febd11ae2af603e449eb841f57746151e3185cb5b2494d959867a4bf80c721c6bd20debac3a1041a29e706e165881e8384a1583b600441d8bf2d36a3d0f1e9bda28187534c6c0f4b90631fdf44a7b647ae39da9285ab494e4fe92132817345bebab4c0aa8ad60e1010fea588648eb15b0fe20c039127ea94f36315a91bfc637f827f2f3b46790c06ab1348bc56d7eaa5563c6f104727fa9a134d988df57d750944e38c6ae3bc0a4be12d4e8c20685cc30808bc5a66a14094d733fe08be61c1335b8f8fbb4190098ed697ed1e0896434add7281ddb1d95a0a266741e630058a61b549c44d6efd0fd9833113e2d0ac4fbe427e41239a61417009bd0992b46e9c30d1431f91d43a0f9fdeaf969185decab082287fd4d69ee1d0fbf3aec85b10bddf09944f6dd5bc09eb2f4e9a1e4c13a71296d21d33729b95beb6d145ed886da6e47d63baa6f20f0287f2c6860911d519025bf9cc5156d6a0909c156479967b2d9dd337337c0986072491d5552264cbdb310c75be84dd7684017d3b2edc4c98b3ed2414b5b5f5580d8be9a913347391c26abebfb67da10ef4fcbe89f1a8535e0dab21b869f72cd40530cc936e0c83d23e240a651ce2f09724f06e190b402ea51609c3a0b83473100b7fd2bbdfd9c6b069185d73d124284cb776c02a748bc6ae70204c3fe8822d5d02086ad8f175f86afca8ebeef8d86fad9abad7019e76b9445008ea8db19e5e1d070abb6a9f3d8db85db66a7f6ced71fa87eed80522a1dd524c1c10c324ad53fc0bbc9846e43408f73408bc14c1322af232702012a6b2a321541785449639362e0891b557e580ed7c9d1a42985bb7e0739bea47b1b554ea562930d9828e68d4c90b2414f7eb8a7dd49c9be8e4f692ce071940bea5d8edd7ed0f2bef20322d0a2b07f621761f5e04b57dc6a3c6bede60d2409be0b1cad4b562e9adb74a2aaada8b0f57f5959cd2711ce263b9900dace4adbbae4f0fa8d1a1d8a5caadeae31da54e042369ebff41cc410a0d2e9f97138b04a310dcf5b2687125b96c579be73dae1f060d07c3283b6c5c6330d395fe50c762ea8fa50150a981543c78afab5ef52d260a6e8a92840e40884f5c96d850dc8f9ba0942b283a330632751bb836fd41c95e0d0c9f53e8a3c08b4a78d028064bad31e6527b06d5191f4c90c380c18b28bb720e81fffaf20e673560bc4b52512e53466a6345e69a1cfe20c420489252e9347a0dc0d74a5dbc4cddd40744dc665f68d046ec32460d727b4303d2d238c91324e7063d08c5cf208787191fae274bb5282cd2a35c9ebc901f86cfd6c75f8e64c6fe01ea3fb9304afdae3d400e9e5f743abba658e997ed7690abcf9ea91af217e8c70f34b15dcd3465d01a66d4ff083d2cd31bc48941ec822b42abcb2029fb91a5c40affb45cc508799039b7cce1cf1da9deb4d05d0596951870d1e25d9df7ae0a47014febcb7d8372ac26edd2b5c22b30bcae9ac062cb13510a36be13173d584ca905131a357a61b1014f4345b151b8e5e92f35b373d550099ce609f85509f34d8c00283c310a6672c3c991cb7be339f3758bc068af8421af960d4e6fe046f9479d063631fb228a2118659cfa11a40e6f1ff14c2dce6398348e99d9abc95e9b33aa058e5f4520a74e7f90a14383a38d224c6e2e25f26ba6a20331ff779cb3351c770fcb9217428693637dc94f5b7174a0a6ad9f15779f089c7215c276d909c644b00814443f24840c9cafde250ee9ed9babae6d54348f1077835666162c16b94a8b045ae832dd4533114673d07c6c1050529948d1ae2c11b11b313bc532475027f10bdadb56cf435e7d7971d2e8f3e753aba45a73b6165351c527aa82dafb5bc96e0de711fbe97c882304d0d0b60d1e016154edbf025b27a9758d3c0714b98547d60c9fdcb582ee35b47ecc8dc7181331c9b1d86dde991731a3ad26a42b053422e105f5b403e6ddadf58066eac7f69e6f0bee96de29cd67960179bf46167685aa95062c044ac38550605635e61a30040803bc5de228fd3c75df292adae7f96e97b50d942f974f84e4261aeb67dd37ca2800a4cae6ac6f89aa687c36462388d06aa808a12d75a3ba0185dc02c41853c470f049f10c166c135603f8dc0cf11b90552c07be245135fb0f2dee11a10d68bcaafd2e5a7b9b0ed419265b9e69c8f8cf67a2074dee2f5387e3678c88511f792cf5003097b849c4cb26c247924dc9ddda75b00cf474ef873af79bb9eb95a01a484aec6e5297f39389f2942a66e1d406c02fd6063d546a1508d383fd6972bbd415e8a2bfce04fd1588a6a4be1a5a32368ddbd80ca86d256374ab90ab120a39c97932242d55745c7e50a8480183a3421228d7050acbfc3075cc333284b2cb108618382e27ded11635054e4325f34f22ad965d040f6efefcb52894245a25111e0d9242acba77866606d21a142853ae684029bd6c0a6f4c1736dffbe610b469f94fa279af7d998fd8d2dd2a15e16b8b9030bdba4502b40505d49b280257cc2617b1cf4119da6363a4737f368eaea3afcd4f26524e086ff827d85dbbc296cd29aec76c4fd16a1ef7dabda71165c44ea7c01ce79e400b00c94e6fc70b250c80a0021e084b63b1e819b1e424e410d290437cda1075eb0ce37b2b7ef24e21850d9b54a19febdd3a3bef5fa338039c7881d0cbeab251e9013b1126d5e4e28d07452ee914de825d797636b4eef0e6d189e10b57eadea8d9007c155340a560c16aa19d167dd6fd040f4331c26f212fa855186bdb3ba7118f0f31f46a3500e59ad379ee9b0f672b0d14c70f796225efcf4c3aa7976b4d55c30d2aa07dce2adbdc8e6086ad23d1c7128f7234e1663bcf8beb3b11dd92802aef050b84617870a2e9273b255c132ca15daabed0a8e5519e533c04e19c43f6ebf30bfee5457e8715563c8cda0908c5f34719952f73f0f47f7365eac3c141c952f40203b51cf3fe5b4a31fe3e277a672d62ac9fa7a959025ab53484202b99a3376d0c8cb1d731f175a32935b2d8132fe5732b6826d808a47da7fcaf26786afb890d0d1016807405fe83a6c66cc32b30e6b9d4dc009f99e2ae2b5f63e8e275c2cd020d5b41d607563f55ffe73814759edc4d9101aa329ecaa072bf7f7bbc49877a5b0e83ef4e00bdb30d25d05879456c23ec567c1da0ef446bd44adfc3e6b0d63fb80c970a123ffada559fdd01ab5f414d08738992f579cb8e2bf26e58f5b3b542700d334c18b84a13de3ebeafeb3d323cccf26b25881cad6f295556eb7c987ee7e20e21be221543f126ef2534bc9377adf19e0e089902fbe1ffb85b61adbf3a1e8b0bf4466b858b5890d8a7cb24e8d08371dfdae2bf938bb38ee6970c8197e8b617049f051268d811cf603d60c627bf62b3ac2b75607d7a5d32ded4d0efd356d3290c183be51fe8013eafda7d1cd7190ffeee31452d5cacbd4450183fac431bfd1d01d91851a8c004a835a2a94d84507f1a780d4c1eb8113273354659557ca09d95054a43d530059137ec28e634a5047f3ce418278541e403e3d7608cc31d9894f50de25b72a4ff702bd76cdb2ed882bcea950d46a0a8682840505b200cbe8311bd0ae16f88984ed477eedf14255cd2d97f33480394aed917f4fe28ce071d5297dc091a0d140e3f99fe443234ed576ae72d350f4d38e67366128a71abe82154fc790b5763d884e9c6b9af192b478729d9f9916962f9c19587026a7395e08a5cb63e0155f894972c6ffa01472bff97ec0caca6fabf87bc28e9e1ffd9462869993a9d078611549c92308373020c9ecb9a3b86944e7b4f199c2dcee420156194be699a06987497eea31cbaadaaec42236ba0d80b6804c78ccbfd971ee496d584d7d3c507f9af01d265d76789df6bbb417a283612e6f178bdfbb5c4ff07bd46f98d2d30001b3dce937b3b13bba358c0c49ac67bc566e6b1126a223d0af1252af3c902450affb12da52b40dc4eb6c593ec6e8dc92210913aa919e2e5662d4bde6d1fd42b0205ee7d7fdc67acfdf2cd67692e4f62cda107e810652f4c97745f556bae6ac3093b1e3d9752ef7e984eaa6372343d29b70dd25bd4f3ea5c08b4d0f31d346e5a0c0445dfc0d41e7955db1eeceec7ff44f06fb84dcb1cf361e512874cad985a9901da3b2f67204f0165e589ebd4e3739df173a7cc8ed08107c4d442121b15b85c0bc0727f6e8073877654aacb4e393a868d6054f413cd899cf4176899facef4ac052cdea604386937c07e4a086ed6be26a7423f9a32c1d7e915426dd8b2083f5004b26d99ad716e7eb55c6d191513e7ecab08c82cd7b29dba583f4f59aa4cabe20242db63f15cfbddb908e643c5e1a99a5d155597968018c643672d05250dd0ab0db36c1cb3060b06c4fdc4ec21623f4fcd1105177dd44afd797dea3d155aa07f91e6cacadc6a2a85d57d6ddc143d46273bf30e6b5158c46d2c4c01ec0e2c4d51b9f09294a9e68bf753060797cce8f2ae2ffb0b793bf3e4bc4c8c88a6061e2a05fac39ce719ff929cee369b09241a16d41ffa091e31e5652467c8e829ae8475e48710fa40065d128314c5bbbcb38431eb468e9f2bf4f706525bb745c47d54c661a1aa371fcce5adbef14daef7a38e64d1cf64d9954df0f9bd9437f347e63888a7586f87b64e8ec576239731707c8f8d8cb93ee931b967b8fd7c8c7e1a320914f63f60bf64f0200b5249d53c47ab22428b1a839b3bb8f0e025781629bf5a388e0b78214d44b81df02cd678fbe17eb5ca68970487d89fccfa4e94e2f7a83cee2d90e9c71f8d270f7b6b562504728f191c782848893be3f1397a68e2206ed3deb2e489555a5db07077175a6f89689f18f62333565824b29fdaef57a8a0d2c44520fd9bfd13d13aa03b342b1224f6ee540c45dc7ea243915d952f4e1334a98543474019650199807f28e9eaa2a2dab2d93a4c84d46e7261a499e923876acd07c834d768e8f6b5b7eb68990b034ebc9cb51e6aaa5edc747b9529b47ce258433a49c6c4754f139521780ef0657f1c32171c6334dfaf1f009c472383878620e2d5c2a61274c2c913dd7d5cfe470c1578088de9c13376da463984e6b3b3d56f1db3b1f5b059dad3d4b663dfeecdf84566d7745b4465a753085e335312ef4f119ba5f54560b8aadfa7b95b370ac5a4ddd55cbb5fdf233043f6af938692e1a634a5a29f190499f4a4914f144ec98fbdf2580564f759771420950ec81f78b486b11fd853f3b014743f2d5b518ceed7b842302b59b6ad313c88c113efeafc91c7291fd56b22507816ef31942e4b575b6f7552a0f3d5fdecf62fd17ced74da69c4c0a81f058b0f70fcd0c5beed103cea702f1f773b72cf20f146281d0d6213632c76f9fdad1123aa61430523a63b212e907056dce796e05886723ef12f16eb546402ce75cbca06c466ed98661551a5cd7b8dd0ed690de21d5dd14fa07914d81fdc662ef00fde7b48a62585895b563a0d350ebc6f574505a136e17888f07955c1889f3a145ebeef02d5d41386357ecdae636c218271b03f5a9f3836c600239870310c77138cda8380697d130866a8bb5f703c83c7fedb0164c0379942990f00c44e6c450388a7bbc3367e7e7adf64cf47d939a02a2498bc6c4a7026746a93f17585b7b72e9832011508e9b1e05c7e98793b96c8274e0df40b7513093841d6d6c019990bd5e38d0512ade72de29e5ca600aef169dc559acbcc3dd61262189ddc33f3684d95e808aa442b5361a798dc93855be1d4c6e79f34ccefca0e4175b2cd9010149cd85331533f5909f188958b3171dd7871f9a9433a22046d73d85f1670d0824ac4bf5867d40d40049d934922d251934a1956e5dc9a91d621f74edacc340d2a1f410998f800756e3f73fbe7f9c63cd2d997bcb5dcdf0b83189be20e0fb0ccfe592c07410b13d725067aa5a86e85b6f8e9abcc5cc95cb309ea83ee90073fa641ed8802a0c69286cd3ce6f1d7962f7d22e1d1888acf0b89e957598cf10054b9fa56da95f4485a308b4ce449ce0d3f95713ad846aa1c0aad321a6d0758e1ba379bd7ea2d6c9b88e3c8f77d53c67d62f16367ab1414175cd4553145db1c18430a0b57892954893fa7eb08d59c010de9895e551c6a0124013a6e275502560c387393d003e119fc31a5390977e87c248caa76fdaf4fb96d95d31808c18887d1034eeb50c2048df01d3e12210806788f8aa4bd3888ff2c197a5126a0006a1a144bab24a8fc847b279e53b0564657cff91610a1dd32f823d508d13d7acdf27fc52a12755aeb3d42243c0aa22c00c062d12548bc4a0c3dbfe2bc8e809775b05393c051e7c738118b92573f0bacae19d83bf9834f1588285725b68fc35d9d41645d114aab9b6b4f1fd90e19975de1bc503d658416bb1e49b64777d53a74053b9b96d266cbb8c39d0a69ac95a83b81dcd1cde3b96df6683e98bfd8f11a49b48f64c91dd4b12387cd7799d330459edff38c0acbb3754848d6a07cd14fd646cab8c1dcf0f0b4c542c6a771d72aca6f0c29bc3606d9f5207fa257217df2e60cdc77a9e85af532d54eab6dd1aaddf585c46c3a903941d6fc063038c3a5c9486f944eb49dce4a3e002e553884522b6b151f7c1c1f37d91a15bb41c8320aa51f597744d2ca7e3ce9c90639de83d6b880fff4f1d56cd0e9480992a37827e4b6464bc38b4dce268287fc9f1f2b6efed4cbd11f32e52a8d40e3284170203e30c88b8483aadf99c299cd4e0865cb227166df1443b7d52870edc2587e0db66616cfc35e38029d741f02253c82dab5e1bbd25c5e029e582c0c71c507a1daa591057072f704a26bea31f72801b5029dfd9d9566c724cd5591ab305621d55ba94daea5b1712725963c58e196e68049108c80a95f7193bfe3b7f1dfdcc1de72eead76074dee6868bab6a32b7dd0758a85799628cd5c7f3be18459ca6f9537693df592af4e1f825d42392559089e8b42f3953e96a964f9c4fd5fa85f677cddc254f9a876cc2730bef01f02befe5d84a66ca46af751975579a6629f4e74c42927e5e2bff00c9b000ae5dd482efbd9717a7b79a183ca219a65477a1e2bde3386a8669d1bb149ffcc38b60b47108971d90cea564971f219816b99f592f2f230b5b86b9198a98abe982d2c0b0e5f40dd3697c23c6431b60088b2dc2a95f0c70214983d7a0015048e22fc3801b26119d38d435aafba92bb3b62b24d7fdfebac496e4e5f080b4e1f16ac2f4e0116ac7d9f16e2c945e7ce729f3e26612bcf37ce4c5bc34a553a5606e5f0624a61c0209bfa0a4c7ae3aa541b1ad71d9bf3fad478ca04bb53f3e7495b64c4951ffa530f4ccb1442fd5e350d581edcb9719cf3fc319fd9bca34a99c64d3f3ccda3f039522b459a7b95944e03dd3184611f82a88779a8c370390dd1039ecfa280d715ca8aa3dc5eacfbdbcc08ab4a579f62d6f2f9a7a67d96362c5a30245a6f412ba53ca6a276f632e765560e9e801949bf806f7557942a39700bd0dab24eecc510702a5f7fcfc7af70f37e040cbcb3d0bc6a2aa6107a2466685787ea9454e98d4b48789791017a6f3db37305e606dc12adabfc8d4f9d0651806e1ac2aafdad4762ec81487da70b2871eb8206b51abfb0b4694d563007fa000213182cea6ab976672f980300536258a409830a5f705537b93277250e1dddd77db1167cfdadea4ed4e6d0760b7aac94091b610aece5247b34c5ed042ca09a1a352014aad17a2141ac4c821ba4c8371d49cfd0008c3ef6c307e54f6decd2f6ee99d8de36a0a50d2f257919f30b48c8d22ac9ad0c" 139 tx_data_blob, _ := hex.DecodeString(tx_data_hex) 140 141 var tx Transaction 142 143 err := tx.DeserializeHeader(tx_data_blob) 144 145 if err != nil { 146 t.Error("DeserializeHeader transaction from project dero blockheight 72 2c4738d3856e8e3e8f9fc4818a9197d4911af3010e067ec56d08c264627cb547\n") 147 return 148 } 149 150 // now serialize once again 151 /* 152 serialised, _ := lheader.Serialize() 153 if raw_data != hex.EncodeToString(serialised){ 154 t.Error("Serialize Levin_Header Failed") 155 } 156 */ 157 158 } 159 160 // test all error cases, except ring signature cases 161 func Test_Edge_Cases(t *testing.T) { 162 163 tests := []struct { 164 name string 165 txhex string 166 }{ 167 { 168 name: "Invalid Version", 169 txhex: "80808080808080808080", // Major_Version is taking more than 9 bytes, trigger error 170 }, 171 { 172 name: "Invalid Unlock time", 173 txhex: "0280808080808080808080", // unlock time is taking more than 9 bytes, trigger error 174 }, 175 176 { 177 name: "vin length cannot be zero", 178 txhex: "020200", // vin length cannot be zero, trigger error 179 }, 180 181 { 182 name: "Invalid vin length", 183 txhex: "020280808080808080808080", // invalid vin length is taking more than 9 bytes, trigger error 184 }, 185 186 { 187 name: "Miner TX vin is invalid", 188 txhex: "02" + // version 189 "3c" + // unlock time 190 "01" + // vin length 191 "00" + // vin #1 192 "80808080808080808080" + // height gen input 193 "01" + // vout length 194 "ffffffffffff07" + // output #1 amount 195 "02" + // output 1 type 196 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 197 "21" + // extra length in bytes 198 "01" + // extra pubkey tag 199 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 200 "00", // RCT signature none 201 }, 202 203 { 204 name: "Miner TX height gen is invalid", 205 txhex: "02" + // version 206 "3c" + // unlock time 207 "01" + // vin length 208 "ff" + // vin #1 209 "80808080808080808080" + // height gen input 210 "01" + // vout length 211 "ffffffffffff07" + // output #1 amount 212 "02" + // output 1 type 213 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 214 "21" + // extra length in bytes 215 "01" + // extra pubkey tag 216 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 217 "00", // RCT signature none 218 }, 219 220 { 221 name: "TX Vout length is invalid", 222 txhex: "02" + // version 223 "3c" + // unlock time 224 "01" + // vin length 225 "ff" + // vin #1 226 "50" + // height gen input 227 "80808080808080808080" + // vout length 228 "ffffffffffff07" + // output #1 amount 229 "02" + // output 1 type 230 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 231 "21" + // extra length in bytes 232 "01" + // extra pubkey tag 233 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 234 "00", // RCT signature none 235 }, 236 237 { 238 name: "TX Vout amount is invalid", 239 txhex: "02" + // version 240 "3c" + // unlock time 241 "01" + // vin length 242 "ff" + // vin #1 243 "50" + // height gen input 244 "01" + // vout length 245 "80808080808080808080" + // output #1 amount 246 "02" + // output 1 type 247 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 248 "21" + // extra length in bytes 249 "01" + // extra pubkey tag 250 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 251 "00", // RCT signature none 252 }, 253 254 { 255 name: "TX Vout type is invalid", 256 txhex: "02" + // version 257 "3c" + // unlock time 258 "01" + // vin length 259 "ff" + // vin #1 260 "50" + // height gen input 261 "00" + // vout length 262 "80808080808080808080" + // output #1 amount 263 "02" + // output 1 type 264 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 265 "21" + // extra length in bytes 266 "01" + // extra pubkey tag 267 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 268 "00", // RCT signature none 269 }, 270 271 { 272 name: "TX Vout type not VOUT_TO_KEY", 273 txhex: "02" + // version 274 "3c" + // unlock time 275 "01" + // vin length 276 "ff" + // vin #1 277 "00" + // height gen input 278 "01" + // vout length 279 "ffffffffffff07" + // output #1 amount 280 "00" + // output 1 type 281 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 282 "21" + // extra length in bytes 283 "01" + // extra pubkey tag 284 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 285 "00", // RCT signature none 286 }, 287 288 { 289 name: "TX Extra length cannot be invalid", 290 txhex: "02" + // version 291 "3c" + // unlock time 292 "01" + // vin length 293 "ff" + // vin #1 294 "00" + // height gen input 295 "01" + // vout length 296 "ffffffffffff07" + // output #1 amount 297 "02" + // output 1 type 298 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 299 "80808080808080808080" + // extra length in bytes 300 "01" + // extra pubkey tag 301 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 302 "00", // RCT signature none 303 }, 304 } 305 306 for _, test := range tests { 307 tx_raw, err := hex.DecodeString(test.txhex) 308 if err != nil { 309 t.Fatalf("Tx hex could not be hex decoded") 310 } 311 312 var tx Transaction 313 err = tx.DeserializeHeader(tx_raw) 314 315 if err == nil { 316 t.Fatalf("%s failed", test.name) 317 } 318 319 } 320 321 } 322 323 // test panic if transaction is without ins 324 func Test_Edges_Serialization_0inputs(t *testing.T) { 325 defer func() { 326 if r := recover(); r == nil { 327 t.Fatalf("Transaction did not panic on 0 inputs") 328 } 329 }() 330 331 // The following is the code under test 332 var tx Transaction 333 tx.Serialize() 334 } 335 336 // test panic if transaction is without outs or unknown vouts type 337 func Test_Edges_Serialization_0outputs(t *testing.T) { 338 defer func() { 339 if r := recover(); r == nil { 340 t.Fatalf("Transaction did not panic on 0 outputs") 341 } 342 }() 343 344 // The following is the code under test 345 var tx Transaction 346 tx.Vin = append(tx.Vin, Txin_gen{Height: 99}) // add input height 347 tx.Serialize() 348 } 349 350 // test panic if transaction is without unknown vouts type 351 func Test_Edges_Serialization_invalidoutputs(t *testing.T) { 352 defer func() { 353 if r := recover(); r == nil { 354 t.Fatalf("Transaction did not panic on invalid outputs") 355 } 356 }() 357 358 // The following is the code under test 359 var tx Transaction 360 tx.Vin = append(tx.Vin, Txin_gen{Height: 99}) // add input height 361 tx.Vout = append(tx.Vout, Tx_out{Amount: 0, Target: "NULL"}) 362 tx.Serialize() 363 } 364 365 // test panic if transaction is invalid version 366 func Test_Edges_Invalid_version(t *testing.T) { 367 368 // The following is the code under test 369 // mainnet genesis tx 370 Genesis_Tx_hex := "" + 371 "02" + // version 372 "3c" + // unlock time 373 "01" + // vin length 374 "ff" + // vin #1 375 "00" + // height gen input 376 "01" + // vout length 377 "ffffffffffff07" + // output #1 amount 378 "02" + // output 1 type 379 "0bf6522f9152fa26cd1fc5c022b1a9e13dab697f3acf4b4d0ca6950a867a1943" + // output #1 key 380 "21" + // extra length in bytes 381 "01" + // extra pubkey tag 382 "1d92826d0656958865a035264725799f39f6988faa97d532f972895de849496d" + // tx pubkey 383 "00" // RCT signature none 384 385 tx_data_blob, _ := hex.DecodeString(Genesis_Tx_hex) 386 387 var tx Transaction 388 389 err := tx.DeserializeHeader(tx_data_blob) 390 if err != nil { 391 t.Fatalf("Geneis Transaction could be deserialized") 392 } 393 394 defer func() { 395 if r := recover(); r == nil { 396 t.Fatalf("Transaction did not panic on invalid version") 397 } 398 }() 399 400 tx.Version = 3 401 tx.GetHash() //panic since version is unknown 402 } 403 404 // this tx data is from our blockchain 405 // txid 0dafab1f561c845e0163124e9dbf0c938b2cf157d47c3cab6aafd27f9b25a42b 406 // height 730 407 func Test_Vin_Edge_Cases(t *testing.T) { 408 /* 409 // entire TX manually being decoded, so as tests can be written to edge out faults 410 tx_hex :="02" + // version 411 "00" + // unlock time 412 "02" + // 2 vins 413 "02" + // vin type INTO_KEY 414 "00" + // amount of first vin 415 "05" + // mixin 416 "0b" + // first mixing 11 417 "da01" + //// second mixing 218 418 "8402" + // thirsd mixing 260 419 "3b" + // fourth mixin 59 420 "55" + // fifth mixin 85 421 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 422 "02" + // vin type INTO_KEY 423 "00" + // amount of second value 424 "05" + // mixin of second input 425 "58" + // first ring member 58 426 "74" + // second ring member 116 427 "a503" + // third ring member 421 428 "08" + // fourth ring member 8 429 "15" // fifth ring member 21 430 431 // remaining part ignored as not required for testing 432 433 */ 434 435 tests := []struct { 436 name string 437 txhex string 438 }{ 439 440 { 441 name: " Version NOT equal to 2", 442 txhex: "03" + // version 443 "00" + // unlock time 444 "02" + // 2 vins 445 "02" + // vin type INTO_KEY 446 "00" + // amount of first vin 447 "05" + // mixin 448 "0b" + // first mixing 11 449 "da01" + //// second mixing 218 450 "8402" + // thirsd mixing 260 451 "3b" + // fourth mixin 59 452 "55" + // fifth mixin 85 453 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 454 "02" + // vin type INTO_KEY 455 "00" + // amount of second value 456 "05" + // mixin of second input 457 "58" + // first ring member 58 458 "74" + // second ring member 116 459 "a503" + // third ring member 421 460 "08" + // fourth ring member 8 461 "15", // fifth ring member 21 462 463 }, 464 { 465 name: " Amount NOT ZERO", 466 txhex: "02" + // version 467 "00" + // unlock time 468 "02" + // 2 vins 469 "02" + // vin type INTO_KEY 470 "05" + // amount of first vin 471 "05" + // mixin 472 "0b" + // first mixing 11 473 "da01" + //// second mixing 218 474 "8402" + // thirsd mixing 260 475 "3b" + // fourth mixin 59 476 "55" + // fifth mixin 85 477 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 478 "02" + // vin type INTO_KEY 479 "00" + // amount of second value 480 "05" + // mixin of second input 481 "58" + // first ring member 58 482 "74" + // second ring member 116 483 "a503" + // third ring member 421 484 "08" + // fourth ring member 8 485 "15", // fifth ring member 21 486 487 }, 488 489 { 490 name: " Amount Invalid", 491 txhex: "02" + // version 492 "00" + // unlock time 493 "02" + // 2 vins 494 "02" + // vin type INTO_KEY 495 "80808080808080808080" + // amount of first vin 496 "05" + // mixin 497 "0b" + // first mixing 11 498 "da01" + //// second mixing 218 499 "8402" + // thirsd mixing 260 500 "3b" + // fourth mixin 59 501 "55" + // fifth mixin 85 502 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 503 "02" + // vin type INTO_KEY 504 "00" + // amount of second value 505 "05" + // mixin of second input 506 "58" + // first ring member 58 507 "74" + // second ring member 116 508 "a503" + // third ring member 421 509 "08" + // fourth ring member 8 510 "15", // fifth ring member 21 511 512 }, 513 514 { 515 name: " Mixin Invalid", 516 txhex: "02" + // version 517 "00" + // unlock time 518 "02" + // 2 vins 519 "02" + // vin type INTO_KEY 520 "00" + // amount of first vin 521 "80808080808080808080" + // mixin 522 "0b" + // first mixing 11 523 "da01" + //// second mixing 218 524 "8402" + // thirsd mixing 260 525 "3b" + // fourth mixin 59 526 "55" + // fifth mixin 85 527 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 528 "02" + // vin type INTO_KEY 529 "00" + // amount of second value 530 "05" + // mixin of second input 531 "58" + // first ring member 58 532 "74" + // second ring member 116 533 "a503" + // third ring member 421 534 "08" + // fourth ring member 8 535 "15", // fifth ring member 21 536 537 }, 538 { 539 name: " Mixin member Invalid", 540 txhex: "02" + // version 541 "00" + // unlock time 542 "02" + // 2 vins 543 "02" + // vin type INTO_KEY 544 "00" + // amount of first vin 545 "05" + // mixin 546 "80808080808080808080" + // first mixing 11 547 "da01" + //// second mixing 218 548 "8402" + // thirsd mixing 260 549 "3b" + // fourth mixin 59 550 "55" + // fifth mixin 85 551 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 552 "02" + // vin type INTO_KEY 553 "00" + // amount of second value 554 "05" + // mixin of second input 555 "58" + // first ring member 58 556 "74" + // second ring member 116 557 "a503" + // third ring member 421 558 "08" + // fourth ring member 8 559 "15", // fifth ring member 21 560 561 }, 562 563 { 564 name: " Mixin size huge", 565 txhex: "02" + // version 566 "00" + // unlock time 567 "02" + // 2 vins 568 "02" + // vin type INTO_KEY 569 "00" + // amount of first vin 570 "ff7f" + // mixin 571 "0b" + // first mixing 11 572 "da01" + //// second mixing 218 573 "8402" + // thirsd mixing 260 574 "3b" + // fourth mixin 59 575 "55" + // fifth mixin 85 576 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 577 "02" + // vin type INTO_KEY 578 "00" + // amount of second value 579 "05" + // mixin of second input 580 "58" + // first ring member 58 581 "74" + // second ring member 116 582 "a503" + // third ring member 421 583 "08" + // fourth ring member 8 584 "15", // fifth ring member 21 585 586 }, 587 588 { 589 name: "Different mixin for different inout", 590 txhex: "02" + // version 591 "00" + // unlock time 592 "02" + // 2 vins 593 "02" + // vin type INTO_KEY 594 "00" + // amount of first vin 595 "05" + // mixin 596 "0b" + // first mixing 11 597 "da01" + //// second mixing 218 598 "8402" + // thirsd mixing 260 599 "3b" + // fourth mixin 59 600 "55" + // fifth mixin 85 601 "779360329acf752076a97c5bb58b836a9b2da8820b9268945fcb40328740a3f7" + // 32 byte vout key 602 "02" + // vin type INTO_KEY 603 "00" + // amount of second value 604 "04" + // mixin of second input 605 "58" + // first ring member 58 606 "74" + // second ring member 116 607 "a503" + // third ring member 421 608 "08" + // fourth ring member 8 609 "15", // fifth ring member 21 610 611 }, 612 } 613 614 for _, test := range tests { 615 616 tx_raw, err := hex.DecodeString(test.txhex) 617 if err != nil { 618 t.Fatalf("Tx hex could not be hex decoded") 619 } 620 621 var tx Transaction 622 err = tx.DeserializeHeader(tx_raw) 623 624 if err == nil { 625 t.Fatalf("%s failed", test.name) 626 } 627 628 } 629 }