{"id":394272,"date":"2024-06-29T11:30:40","date_gmt":"2024-06-29T11:30:40","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=394272"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=394272","title":{"rendered":"<span>\u041a\u0430\u043a \u0432\u043e\u0439\u0442\u0438 \u0432 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 Java \u0438 Kotlin: \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c JVM SDK \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0421\u0442\u0435\u043f\u0430\u043d, \u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 Waves Enterprise, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u2014 \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u0430. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0430\u0448\u0435\u043c SDK \u0434\u043b\u044f JVM-\u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0430\u0436\u0434\u044b\u0439 Java\/Kotlin-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u044f \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/104\/3a4\/c5e\/1043a4c5e4566e1fcbbf16e8ddf2e238.jpg\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/104\/3a4\/c5e\/1043a4c5e4566e1fcbbf16e8ddf2e238.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b. \u041f\u043e\u043c\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438, \u043e\u043d\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u043e\u043c \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0433\u043e \u0438 \u0447\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0432\u0441\u0435\u043c\u0438 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a Web3 \u0441 \u0435\u0433\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0447\u0435\u0441\u0442\u043d\u044b\u043c \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u043f\u0440\u044f\u043c\u044b\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430\u043c\u0438 \u0441\u0435\u0442\u0438. \u041e \u0442\u043e\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u0432 \u0441\u0435\u0442\u0438 Waves Enterprise, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/company\/waves_ent\/blog\/674086\/\"><u>\u043f\u043e\u0441\u0442\u0430<\/u><\/a> \u043c\u043e\u0435\u0433\u043e \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0420\u0443\u0441\u043b\u0430\u043d\u0430.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0440\u0430\u043d\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u0438 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e, \u0432\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0432 \u043a\u043e\u0434\u0435 \u0432\u0441\u0435\u0445 docker \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0431\u043e\u043b\u0435\u0435 \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f:\u00a0<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043d\u043e\u0434\u0435 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430\u0448 CTO <a href=\"https:\/\/habr.com\/ru\/users\/execc_13\/\"><u>\u0414\u0435\u043d\u0438\u0441<\/u><\/a> \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u0432 SDK \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432. \u0417\u0430\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 SDK \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0431\u044b\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u043e\u043f\u044b\u0442\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d-\u0441\u0435\u0442\u044f\u0445 \u2014 Hyperledger, Ethereum. \u0412\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u044d\u0442\u043e\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 SDK \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b \u0441\u0435\u0431\u044f \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/p>\n<p>\u0412 2022 \u0433\u043e\u0434\u0443 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f opensource-\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u044d\u0442\u043e\u0442 SDK \u0432 <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\"><u>\u043e\u0431\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f<\/u><\/a> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <a href=\"https:\/\/github.com\/waves-enterprise\/we-node\"><u>\u043a\u043e\u0434\u043e\u043c \u043d\u043e\u0434\u044b<\/u><\/a>. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0442\u044b\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c, \u043c\u044b \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043b\u0438 \u043a\u043e\u0434 SDK \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b\u0438 \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u0440\u044f\u0434 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0414\u0430\u043b\u0435\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0439 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d SDK, \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043d\u0435\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b<\/h3>\n<p>\u0412\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u043a \u00ab\u043c\u0435\u0442\u043e\u0434\u044b\u00bb \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430. \u042d\u0442\u0438 \u00ab\u043c\u0435\u0442\u043e\u0434\u044b\u00bb \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u2014 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractHandler. \u041c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 (string, long, boolean), \u0442\u0430\u043a \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 JSON).<\/p>\n<p>\u0422\u0438\u043f \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0431\u043b\u043e\u043a params) \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043c\u0435\u0442\u043e\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438 \u043a\u0430\u043a\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0435\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c. \u0414\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 103 (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430) \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractInit. \u0414\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 104 (\u0432\u044b\u0437\u043e\u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435) \u2014 \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractAction.<\/p>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445 \u0434\u043b\u044f \u043c\u044d\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0430 route HTTP REST \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<h3>\u041f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0430 ContractState<\/h3>\n<p>\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 key-value \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0441 Redis \u0438\u043b\u0438 Hazelcast. SDK \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430) \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 ContractHandler, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 ContractState. \u041e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442, \u0434\u043b\u044f \u043a\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0445 \u043a\u043b\u044e\u0447\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u044b \u0443 \u043d\u043e\u0434\u044b. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0435\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 \u043d\u0435\u0437\u0430\u043a\u043e\u043c\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0411\u0414:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0432\u0435\u0440\u043d\u0443\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u043d\u0430 \u0441\u0442\u0435\u0439\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432 \u043d\u043e\u0434\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 (\u0430\u043d\u0430\u043b\u043e\u0433 \u043a\u043e\u043c\u043c\u0438\u0442\u0430).<\/p>\n<\/li>\n<\/ul>\n<h3>Mapping<\/h3>\n<p>\u0421 \u043d\u0430\u0431\u043e\u0440\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e Mapping. \u0412\u043d\u0443\u0442\u0440\u0438 key\/value \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Mapping \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d, \u043d\u0430 \u043a\u043b\u044e\u0447\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0442\u0430\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u043a\u043b\u044e\u0447\u0435\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b67\/408\/f2e\/b67408f2e0d8fa1c8a05c9cdc5cd52f7.png\" alt=\"\u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u00a0\" title=\"\u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u00a0\" width=\"1456\" height=\"930\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b67\/408\/f2e\/b67408f2e0d8fa1c8a05c9cdc5cd52f7.png\"\/><figcaption>\u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u00a0<\/figcaption><\/figure>\n<h3>\u041f\u0438\u0448\u0435\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442<\/h3>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\"><u>SDK<\/u><\/a>. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u0433\u0440\u0443 \u00ab\u043a\u0430\u043c\u0435\u043d\u044c-\u043d\u043e\u0436\u043d\u0438\u0446\u044b-\u0431\u0443\u043c\u0430\u0433\u0430\u00bb. \u0421\u0443\u0442\u044c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u0443\u044e \u0441\u043e\u043b\u044c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0445\u0435\u0448 (\u043e\u0442\u0432\u0435\u0442+\u0441\u043e\u043b\u044c) \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0438\u0433\u0440\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0442\u0432\u0435\u0442, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043b\u0438 \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0440\u0430\u0441\u043a\u0440\u044b\u043b\u0438 \u0441\u0432\u043e\u0439 \u043e\u0442\u0432\u0435\u0442, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c (\u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435, \u0442\u043e \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044f \u043d\u0435\u0442).<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\/tree\/master\/samples\"><u>Github<\/u><\/a>, \u0437\u0434\u0435\u0441\u044c \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043b\u0438\u0448\u044c \u0441\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0441\u0431\u043e\u0440\u043a\u0430<\/h4>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0432 \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<pre><code class=\"kotlin\">public interface RockPaperScissorsContract {      @ContractInit     void createGame(CreateGameRequest createGameRequest);      @ContractAction     void play(PlayRequest registerPlayerRequest);      @ContractAction     void reveal(RevealRequest revealRequest); }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0435\u0442\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441, \u043f\u043e\u043c\u0435\u0442\u0438\u0432 \u0435\u0433\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractHandler, \u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448 framework \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u2014 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 state \u0438 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"kotlin\">@ContractHandler public class RockPaperScissorsContractImpl implements RockPaperScissorsContract {      private final ContractState contractState;     private final ContractTransaction tx;      private final Mapping&lt;Player> players;      public RockPaperScissorsContractImpl(ContractState contractState, ContractTransaction tx) {         this.tx = tx;         this.contractState = contractState;         this.players = contractState.getMapping(Player.class, PLAYERS_MAPPING_PREFIX);     } }<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 (\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f 103). \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 Mapping.<\/p>\n<pre><code class=\"kotlin\">public void createGame(CreateGameRequest createGameRequest) {         if (createGameRequest.getPlayers().size() > 2) {             throw new IllegalArgumentException(\"Currently only two players are supported\");         }         contractState.put(CREATED_DATE_KEY, txTimestamp().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));         contractState.put(                 PLAYER_ADDRESSES_KEY,                 createGameRequest.getPlayers().stream().map(CreateGameRequest.Player::getAddress).collect(Collectors.toSet())         ); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0445\u0435\u0448 \u043e\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430:<\/p>\n<pre><code class=\"kotlin\">public void play(PlayRequest registerPlayerRequest) {         if (contractState.tryGet(GAME_KEY, Game.class).isPresent()) {             throw new IllegalStateException(\"Game has already started\");         }         String senderAddress = senderAddress();         Set&lt;String> addresses = getPlayerAddresses();         String txSenderAddress = txSender();         if (!addresses.contains(txSenderAddress)) {             throw new IllegalAccessError(\"Address \" + txSenderAddress + \" is not present in the players of this game\");         }         players.put(senderAddress(), new Player(senderAddress, registerPlayerRequest.getHashedAnswer()));         if (players.hasAll(addresses)) {             startGame(addresses);         }     }      private void startGame(Set&lt;String> addresses) {         Game game = new Game(new ArrayList&lt;>(players.getAll(addresses).values()));         contractState.put(GAME_KEY, game);         contractState.put(GAME_STATUS_KEY, game.getStatus());     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u043a\u043b\u0430\u0441\u0441 Game \u2014 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0440\u0438\u0441\u043b\u0430\u043b\u0438 \u0441\u0432\u043e\u0438 \u0445\u0435\u0448\u0438, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0433\u0440\u0443 \u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 Game \u043d\u0430 \u0441\u0442\u0435\u0439\u0442.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0433\u0440\u043e\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0441\u043b\u0430\u0442\u044c \u0441\u043e\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043f\u0440\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 play, \u043f\u0440\u043e\u0432\u0435\u0434\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u0443 Game \u0432 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<pre><code class=\"kotlin\">public class Game {     private Map&lt;String, Player> players;     private Player winner;     private GameStatus status = GameStatus.ACTIVE;      public Game(List&lt;Player> players) {         this.players = players.stream().collect(Collectors.toMap(Player::getAddress, Function.identity()));     }       public void reveal(String address, String salt) {         Player player = players.get(address);         if (player == null) {             throw new IllegalArgumentException(\"Address \" + address + \" isn't among players of the game\");         }         Map&lt;String, AnswerType> hashedAnswers = getHashedAnswers(salt);         AnswerType answer = hashedAnswers.get(player.getHashedAnswer());         if (answer == null) {             throw new IllegalArgumentException(\"Not found matching answer for salt\");         }         player.setAnswer(answer);         if (allPlayersAnswered()) {             finish();         }     }      private void finish() {         status = GameStatus.FINISHED;         if (allPlayersHaveTheSameAnswers()) {             return;         }         this.winner = players.values().stream().max(                 (player1, player2) -> new AnswerComparator().compare(player1.getAnswer(), player2.getAnswer())         ).orElseThrow(() -> new IllegalStateException(\"Winner could not be determined\"));     }      private boolean allPlayersHaveTheSameAnswers() {         Set&lt;AnswerType> differentAnswers = players.values().stream().map(Player::getAnswer).collect(Collectors.toSet());         return differentAnswers.size() == 1;     }      private boolean allPlayersAnswered() {         return players.values().stream().allMatch(player -> player.getAnswer() != null);     }      public Map&lt;String, AnswerType> getHashedAnswers(String salt) {         return Arrays.stream(AnswerType.values()).collect(                 Collectors.toMap(answerType -> Util.hash(answerType + \"_\" + salt), Function.identity())         );     }<\/code><\/pre>\n<p>\u0412 main-\u043c\u0435\u0442\u043e\u0434\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043e\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0437 SDK:<\/p>\n<pre><code class=\"kotlin\">public class MainDispatch {     public static void main(String[] args) {         ContractDispatcher contractDispatcher = GrpcJacksonContractDispatcherBuilder.builder()                 .contractHandlerType(RockPaperScissorsContractImpl.class)                 .objectMapper(getObjectMapper())                 .build();          contractDispatcher.dispatch();     }      private static ObjectMapper getObjectMapper() {         return JsonMapper.builder().addModule(new JavaTimeModule()).build();     } }<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0438\u0439 \u044d\u0442\u043e docker-\u043e\u0431\u0440\u0430\u0437 \u0438 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0432 registry, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u043e\u0434\u0430 Waves Enterprise.<\/p>\n<pre><code class=\"kotlin\">FROM fabric8\/java-alpine-openjdk11-jre MAINTAINER Waves Enterprise &lt;>  ENV JAVA_MEM=\"-Xmx256M\" ENV JAVA_OPTS=\"\"  ADD build\/libs\/*-all.jar app.jar  RUN chmod +x app.jar RUN eval $SET_ENV_CMD CMD [\"\/bin\/sh\", \"-c\", \"eval ${SET_ENV_CMD} ; java $JAVA_MEM $JAVA_OPTS -jar app.jar\"]<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 build_and_push_to_docker.sh \u0438\u0437 <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\"><u>\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f SDK<\/u><\/a>.<\/p>\n<pre><code class=\"kotlin\">.\/build_and_push_to_docker.sh my-registry.com\/smart-contrats\/rock-paper-scissors-contract:1.0.0<\/code><\/pre>\n<h4>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e 103 \u0434\u043b\u044f \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c REST API \u043d\u043e\u0434\u044b.\u00a0<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0441 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438 <em>3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh<\/em> \u0438 <em>3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv<\/em>.<\/p>\n<pre><code class=\"java\">curl --location --request POST 'https:\/\/node-0\/transactions\/signAndBroadcast' \\ --header 'Content-Type: application\/json' \\ --data-raw '{     \"image\": \"my-registry.com\/smart-contrats\/rock-paper-scissors-contract:1.0.0\",     \"fee\": 0,     \"imageHash\": \"2fad12f4de059e29f92e7d31b91b6cf8388bc0cadb2fdfd194b25e21193bd7cc\",     \"type\": 103,     \"params\": [    {             \"type\": \"string\",             \"value\": \"createGame\",             \"key\": \"action\"         },         {             \"type\": \"string\",             \"value\": \"{\\\"players\\\":[{\\\"address\\\":\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\"},{\\\"address\\\":\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\"}]}\",             \"key\": \"createContract\"         }      ],     \"version\": 2,     \"sender\": \"{{address}}\",     \"feeAssetId\": null,     \"contractName\": \"sample-rock-paper-scissors-contract\" }'<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c ID \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u2014 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043c\u0430\u0439\u043d\u0438\u043b\u0441\u044f:<\/p>\n<pre><code class=\"kotlin\">curl --location --request GET 'https:\/\/node-0\/contracts\/GQNK5zxqt1a6cYxnYfG4Svk6HvEjwBdeq61vP2FnNSSp  [     {         \"type\": \"string\",         \"value\": \"2022-07-18T19:22:14.258\",         \"key\": \"CREATED_DATE\"     },     {         \"type\": \"string\",         \"value\": \"[\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\",\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\"]\",         \"key\": \"PLAYER_ADDRESSES\"     } ]<\/code><\/pre>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441 \u0438\u0433\u0440\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u043d \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0441 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438 <em>3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv<\/em> \u0438 <em>3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh.<\/em><\/p>\n<p>\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c <em>3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv<\/em>. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#171;abcd1234&#187;.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c SHA256-\u0445\u0435\u0448 \u043e\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 + \u0441\u043e\u043b\u0438: <code>Util.hash(AnswerType.SCISSORS.toString() + \"_\" + \"abcd1234\")<\/code>. \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0437\u0430\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c <em>3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv<\/em>.<\/p>\n<pre><code class=\"java\">curl --location --request POST 'https:\/\/node-0\/transactions\/signAndBroadcast' \\ --header 'Content-Type: application\/json' \\ --data-raw '{     \"contractId\": \"GQNK5zxqt1a6cYxnYfG4Svk6HvEjwBdeq61vP2FnNSSp\",     \"fee\": 0,     \"type\": 104,     \"params\": [         {             \"type\": \"string\",             \"value\": \"play\",             \"key\": \"action\"         },         {             \"type\": \"string\",             \"value\": \"{\\\"hashedAnswer\\\": \\\"3be42e249759cee0704157b135d2eb192d1cbd32e8a64d3b048d9de499514694\\\"}\",             \"key\": \"arg\"         }     ],     \"version\": 2,     \"sender\": \"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\",     \"feeAssetId\": null,     \"contractVersion\": 1 } '<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430:<\/p>\n<pre><code class=\"java\">[     {         \"type\": \"string\",         \"value\": \"2022-07-18T19:22:14.258\",         \"key\": \"CREATED_DATE\"     },     {         \"type\": \"string\",         \"value\": \"{\\\"address\\\":\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\",\\\"hashedAnswer\\\":\\\"3be42e249759cee0704157b135d2eb192d1cbd32e8a64d3b048d9de499514694\\\",\\\"answer\\\":null}\",         \"key\": \"PLAYERS_3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\"     },     {         \"type\": \"string\",         \"value\": \"[\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\",\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\"]\",         \"key\": \"PLAYER_ADDRESSES\"     } ]<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0430\u0434\u0440\u0435\u0441\u0430 <em>3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh<\/em>. \u0415\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u00ab\u043a\u0430\u043c\u0435\u043d\u044c\u00bb (ROCK).<\/p>\n<h3>\u0417\u0430\u043f\u0443\u0441\u043a \u0438\u0433\u0440\u044b<\/h3>\n<p>\u041c\u044b \u0432\u0438\u0434\u0438\u043c \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 GAME: \u0438\u0433\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430\u0441\u044c.<\/p>\n<pre><code class=\"java\">    {         \"type\": \"string\",         \"value\": \"{\\\"players\\\":{\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\":{\\\"address\\\":\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\",\\\"hashedAnswer\\\":\\\"3be42e249759cee0704157b135d2eb192d1cbd32e8a64d3b048d9de499514694\\\",\\\"answer\\\":null},\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\":{\\\"address\\\":\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\",\\\"hashedAnswer\\\":\\\"8ab8580983b8aa12284773fabb2f07caab18164266a92a3332599beb24629868\\\",\\\"answer\\\":null}},\\\"winner\\\":null,\\\"status\\\":\\\"ACTIVE\\\"}\",         \"key\": \"GAME\"     }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0433\u0440\u043e\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0441\u043e\u043b\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c <em>3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv<\/em>.<\/p>\n<pre><code class=\"java\">curl --location --request POST 'https:\/\/node-0\/transactions\/signAndBroadcast' \\ --header 'Content-Type: application\/json' \\ --data-raw '{     \"contractId\": \"GQNK5zxqt1a6cYxnYfG4Svk6HvEjwBdeq61vP2FnNSSp\",     \"fee\": 0,     \"type\": 104,     \"params\": [         {             \"type\": \"string\",             \"value\": \"reveal\",             \"key\": \"action\"         },         {             \"type\": \"string\",             \"value\": \"{\\\"salt\\\": \\\"abcd1234\\\"}\",             \"key\": \"arg\"         }     ],     \"version\": 2,     \"sender\": \"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\",     \"feeAssetId\": null,     \"contractVersion\": 1 } '<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f \u0432\u0441\u0435\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c \u0438 \u0438\u0433\u0440\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 FINISHED. \u041d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044f \u2014 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c <em>3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh<\/em>, \u043f\u043e\u043a\u0430\u0437\u0430\u0432\u0448\u0435\u0433\u043e \u043a\u0430\u043c\u0435\u043d\u044c.<\/p>\n<pre><code class=\"java\">{         \"type\": \"string\",         \"value\": \"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\",         \"key\": \"GAME_WINNER_ADDRESS\"     },     {         \"type\": \"string\",         \"value\": \"{\\\"players\\\":{\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\":{\\\"address\\\":\\\"3M7EEnszPAT2yr72SgWVDLxfYCa4AYvVRwv\\\",\\\"hashedAnswer\\\":\\\"3be42e249759cee0704157b135d2eb192d1cbd32e8a64d3b048d9de499514694\\\",\\\"answer\\\":\\\"SCISSORS\\\"},\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\":{\\\"address\\\":\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\",\\\"hashedAnswer\\\":\\\"8ab8580983b8aa12284773fabb2f07caab18164266a92a3332599beb24629868\\\",\\\"answer\\\":\\\"ROCK\\\"}},\\\"winner\\\":{\\\"address\\\":\\\"3M3xGmJGmxBv2aZ4UFmn93rHxVXTJDKSAnh\\\",\\\"hashedAnswer\\\":\\\"8ab8580983b8aa12284773fabb2f07caab18164266a92a3332599beb24629868\\\",\\\"answer\\\":\\\"ROCK\\\"},\\\"status\\\":\\\"FINISHED\\\"}\",         \"key\": \"GAME\"     }<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0443\u043d\u0434\u043e\u0432. \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044f \u043d\u0435\u0442, \u0438\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0438\u0433\u0440\u0443 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0434\u0432\u0443\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432.<\/p>\n<h3>\u041f\u043b\u0430\u043d\u044b \u043f\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044e Java\/Kotlin SDK<\/h3>\n<p>\u0412 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c SDK. \u0412 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0435 \u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438 Waves Enterprise, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c <a href=\"https:\/\/docs.wavesenterprise.com\/ru\/latest\/changelog.html\"><u>\u0440\u0435\u043b\u0438\u0437\u043e\u043c \u043d\u043e\u0434\u044b<\/u><\/a>. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u044d\u043a\u0435\u043d\u0434\u0430, \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0435\u0439\u0442\u043e\u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/678062\/\"> https:\/\/habr.com\/ru\/articles\/678062\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0421\u0442\u0435\u043f\u0430\u043d, \u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 Waves Enterprise, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u2014 \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u0430. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0430\u0448\u0435\u043c SDK \u0434\u043b\u044f JVM-\u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u0430\u0436\u0434\u044b\u0439 Java\/Kotlin-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u044f \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b. \u041f\u043e\u043c\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438, \u043e\u043d\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u043e\u043c \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0433\u043e \u0438 \u0447\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0432\u0441\u0435\u043c\u0438 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a Web3 \u0441 \u0435\u0433\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0447\u0435\u0441\u0442\u043d\u044b\u043c \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u043f\u0440\u044f\u043c\u044b\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u043c\u0435\u0436\u0434\u0443 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430\u043c\u0438 \u0441\u0435\u0442\u0438. \u041e \u0442\u043e\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u0432 \u0441\u0435\u0442\u0438 Waves Enterprise, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/company\/waves_ent\/blog\/674086\/\"><u>\u043f\u043e\u0441\u0442\u0430<\/u><\/a> \u043c\u043e\u0435\u0433\u043e \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0420\u0443\u0441\u043b\u0430\u043d\u0430.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0440\u0430\u043d\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u0438 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e, \u0432\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0432 \u043a\u043e\u0434\u0435 \u0432\u0441\u0435\u0445 docker \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0431\u043e\u043b\u0435\u0435 \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f:\u00a0<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043d\u043e\u0434\u0435 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0441 \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430\u0448 CTO <a href=\"https:\/\/habr.com\/ru\/users\/execc_13\/\"><u>\u0414\u0435\u043d\u0438\u0441<\/u><\/a> \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u0432 SDK \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432. \u0417\u0430\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 SDK \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0431\u044b\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u043e\u043f\u044b\u0442\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d-\u0441\u0435\u0442\u044f\u0445 \u2014 Hyperledger, Ethereum. \u0412\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u044d\u0442\u043e\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 SDK \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b \u0441\u0435\u0431\u044f \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/p>\n<p>\u0412 2022 \u0433\u043e\u0434\u0443 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f opensource-\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u044d\u0442\u043e\u0442 SDK \u0432 <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\"><u>\u043e\u0431\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f<\/u><\/a> \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <a href=\"https:\/\/github.com\/waves-enterprise\/we-node\"><u>\u043a\u043e\u0434\u043e\u043c \u043d\u043e\u0434\u044b<\/u><\/a>. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0442\u044b\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e\u043c, \u043c\u044b \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043b\u0438 \u043a\u043e\u0434 SDK \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b\u0438 \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u0440\u044f\u0434 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0414\u0430\u043b\u0435\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0439 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d SDK, \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043d\u0435\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b<\/h3>\n<p>\u0412\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u043a \u00ab\u043c\u0435\u0442\u043e\u0434\u044b\u00bb \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430. \u042d\u0442\u0438 \u00ab\u043c\u0435\u0442\u043e\u0434\u044b\u00bb \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u2014 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractHandler. \u041c\u0435\u0442\u043e\u0434\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 (string, long, boolean), \u0442\u0430\u043a \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 JSON).<\/p>\n<p>\u0422\u0438\u043f \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0431\u043b\u043e\u043a params) \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043c\u0435\u0442\u043e\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0438 \u043a\u0430\u043a\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0435\u043c\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c. \u0414\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 103 (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430) \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractInit. \u0414\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 104 (\u0432\u044b\u0437\u043e\u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435) \u2014 \u043c\u0435\u0442\u043e\u0434\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractAction.<\/p>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445 \u0434\u043b\u044f \u043c\u044d\u043f\u043f\u0438\u043d\u0433\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0430 route HTTP REST \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<h3>\u041f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0430 ContractState<\/h3>\n<p>\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 key-value \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0441 Redis \u0438\u043b\u0438 Hazelcast. SDK \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 (\u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430) \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 ContractHandler, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 ContractState. \u041e\u043d \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442, \u0434\u043b\u044f \u043a\u0430\u043a\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0445 \u043a\u043b\u044e\u0447\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u044b \u0443 \u043d\u043e\u0434\u044b. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0435\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 \u043d\u0435\u0437\u0430\u043a\u043e\u043c\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0411\u0414:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0432\u0435\u0440\u043d\u0443\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u043d\u0430 \u0441\u0442\u0435\u0439\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432 \u043d\u043e\u0434\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 (\u0430\u043d\u0430\u043b\u043e\u0433 \u043a\u043e\u043c\u043c\u0438\u0442\u0430).<\/p>\n<\/li>\n<\/ul>\n<h3>Mapping<\/h3>\n<p>\u0421 \u043d\u0430\u0431\u043e\u0440\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0435\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e Mapping. \u0412\u043d\u0443\u0442\u0440\u0438 key\/value \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Mapping \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d, \u043d\u0430 \u043a\u043b\u044e\u0447\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0442\u0430\u043a\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u043a\u043b\u044e\u0447\u0435\u0439.<\/p>\n<figure class=\"full-width\"><figcaption>\u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u00a0<\/figcaption><\/figure>\n<h3>\u041f\u0438\u0448\u0435\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442<\/h3>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\"><u>SDK<\/u><\/a>. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u0433\u0440\u0443 \u00ab\u043a\u0430\u043c\u0435\u043d\u044c-\u043d\u043e\u0436\u043d\u0438\u0446\u044b-\u0431\u0443\u043c\u0430\u0433\u0430\u00bb. \u0421\u0443\u0442\u044c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u0443\u044e \u0441\u043e\u043b\u044c \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0445\u0435\u0448 (\u043e\u0442\u0432\u0435\u0442+\u0441\u043e\u043b\u044c) \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0438\u0433\u0440\u0430 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0442\u0432\u0435\u0442, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043b\u0438 \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0440\u0430\u0441\u043a\u0440\u044b\u043b\u0438 \u0441\u0432\u043e\u0439 \u043e\u0442\u0432\u0435\u0442, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c (\u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435, \u0442\u043e \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044f \u043d\u0435\u0442).<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/waves-enterprise\/we-contract-sdk\/tree\/master\/samples\"><u>Github<\/u><\/a>, \u0437\u0434\u0435\u0441\u044c \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043b\u0438\u0448\u044c \u0441\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0441\u0431\u043e\u0440\u043a\u0430<\/h4>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0432 \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<pre><code class=\"kotlin\">public interface RockPaperScissorsContract {      @ContractInit     void createGame(CreateGameRequest createGameRequest);      @ContractAction     void play(PlayRequest registerPlayerRequest);      @ContractAction     void reveal(RevealRequest revealRequest); }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0435\u0442\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441, \u043f\u043e\u043c\u0435\u0442\u0438\u0432 \u0435\u0433\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 ContractHandler, \u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448 framework \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u2014 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 state \u0438 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"kotlin\">@ContractHandler public class RockPaperScissorsContractImpl implements RockPaperScissorsContract {      private final ContractState contractState;     private final ContractTransaction tx;      private final Mapping&lt;Player> players;      public RockPaperScissorsContractImpl(ContractState contractState, ContractTransaction tx) {         this.tx = tx;         this.contractState = contractState;         this.players = contractState.getMapping(Player.class, PLAYERS_MAPPING_PREFIX);     } }<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 (\u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f 103). \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 Mapping.<\/p>\n<pre><code class=\"kotlin\">public void createGame(CreateGameRequest createGameRequest) {         if (createGameRequest.getPlayers().size() > 2) {             throw new IllegalArgumentException(\"Currently only two players are supported\");         }         contractState.put(CREATED_DATE_KEY, txTimestamp().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));         contractState.put(                 PLAYER_ADDRESSES_KEY,                 createGameRequest.getPlayers().stream().map(CreateGameRequest.Player::getAddress).collect(Collectors.toSet())         ); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0438 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0445\u0435\u0448 \u043e\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430:<\/p>\n<pre><code class=\"kotlin\">public void play(PlayRequest registerPlayerRequest) {         if (contractState.tryGet(GAME_KEY, Game.class).isPresent()) {             throw new IllegalStateException(\"Game has already started\");         }         String senderAddress = senderAddress();         Set&lt;String> addresses = getPlayerAddresses();         String txSenderAddress = txSender();         if (!addresses.contains(txSenderAddress)) {             throw new IllegalAccessError(\"Address \" + txSenderAddress + \" is not present in the players of this game\");         }         players.put(senderAddress(), new Player(senderAddress, registerPlayerRequest.getHashedAnswer()));         if (players.hasAll(addresses)) {             startGame(addresses);         }     }      private void startGame(Set&lt;String> addresses) {         Game game = new Game(new ArrayList&lt;>(players.getAll(addresses).values()));         contractState.put(GAME_KEY, game);         contractState.put(GAME_STATUS_KEY, game.getStatus());     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u043a\u043b\u0430\u0441\u0441 Game \u2014 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0440\u0438\u0441\u043b\u0430\u043b\u0438 \u0441\u0432\u043e\u0438 \u0445\u0435\u0448\u0438, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0433\u0440\u0443 \u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u044d\u0442\u043e\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 Game \u043d\u0430 \u0441\u0442\u0435\u0439\u0442.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0433\u0440\u043e\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0438\u0441\u043b\u0430\u0442\u044c \u0441\u043e\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043f\u0440\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 play, \u043f\u0440\u043e\u0432\u0435\u0434\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u0443 Game \u0432 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<pre><code class=\"kotlin\">public class Game {     private Map&lt;String, Player> players;     private Player winner;     private GameStatus status = GameStatus.ACTIVE;      public Game(List&lt;Player> players) {         this.players = players.stream().collect(Collectors.toMap(Player::getAddress, Function.identity()));     }       public void reveal(String address, String salt) {         Player player = players.get(address);         if (player == null) {             throw new IllegalArgumentException(\"Address \" + address + \" isn't among players of the game\");         }         Map&lt;String, AnswerType> hashedAnswers = getHashedAnswers(salt);         AnswerType answer = hashedAnswers.get(player.getHashedAnswer());         if (answer == null) {             throw new IllegalArgumentException(\"Not found matching answer for salt\");         }         player.setAnswer(answer);         if (allPlayersAnswered()) {             finish();         }     }      private void finish() {         status = GameStatus.FINISHED;         if (allPlayersHaveTheSameAnswers()) {             return;         }         this.winner = players.values().stream().max(                 (player1, player2) -> new AnswerComparator().compare(player1.getAnswer(), player2.getAnswer())         ).orElseThrow(() -> new IllegalStateException(\"Winner could not be determined\"));     }      private boolean allPlayersHaveTheSameAnswers() {         Set&lt;AnswerType> differentAnswers = players.values().stream().map(Player::getAnswer).collect(Collectors.toSet());         return differentAnswers.size() == 1;     }      private boolean allPlayersAnswered() {         return players.values().stream().allMatch(player -> player.getAnswer() != null);     }      public Map&lt;String, AnswerType> getHashedAnswers(String salt) {         return Arrays.stream(AnswerType.values()).collect(                 Collectors.toMap(answerType -> Util.hash(answerType + \"_\" + salt), Function.identity())         );     }<\/code><\/pre>\n<p>\u0412 main-\u043c\u0435\u0442\u043e\u0434\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043e\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0437 SDK:<\/p>\n<pre><code class=\"kotlin\">public class MainDispatch {     public static void main(String[] args) {         ContractDispatcher contractDispatcher = GrpcJacksonContractDispatcherBuilder.builder()    <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-394272","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394272","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=394272"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394272\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=394272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=394272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=394272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}