{"id":343696,"date":"2023-01-09T15:02:35","date_gmt":"2023-01-09T15:02:35","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=343696"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=343696","title":{"rendered":"<span>\u041c\u0443\u043b\u044c\u0442\u0438-\u043f\u0440\u043e\u043a\u0441\u0438 \u0441\u043c\u0430\u0440\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 EIP-2535 \u00abDiamond\u00bb<\/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<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=42TUqDW74v8\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e-\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/davydovMikhail\/multi-proxy-contract\" rel=\"noopener noreferrer nofollow\">GitHub<\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043f\u0440\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 EIP-2535, \u0442\u0430\u043a\u0436\u0435 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043a\u0430\u043a Diamond \u0438\u043b\u0438 Multi-Facet Proxy. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0435, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0441\u043c\u0430\u0440\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u0440\u044f\u0434\u043e\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u043f\u0435\u0440\u0435\u0434 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430\u043c\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u043a\u0430\u043a Transparent \u0438 UUPS.  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 Diamond \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:  <\/p>\n<ol>\n<li>\n<p>Diamond \u0438\u043c\u0435\u0435\u0442 \u0435\u0434\u0438\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 proxy \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a\u043e \u0432\u0441\u0435\u043c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u043c, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043c\u0430\u0440\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>Diamond \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u0441\u0435\u0445 \u0432\u0430\u0448\u0438\u0445 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043b\u0435\u043a\u043e \u0437\u0430 24 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0438\u0431\u043a\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0433\u0440\u0430\u043d\u044f\u043c\u0438(facets), \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430\u043c\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0442\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430, \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u0430 \u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0430. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432 \u043f. 2 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043d\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 Diamond \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c, \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443, \u043b\u0438\u0431\u043e \u043f\u043e \u043f\u0440\u043e\u0448\u0435\u0432\u0441\u0442\u0432\u0438\u044e \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c Diamond \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c.<\/p>\n<\/li>\n<li>\n<p>Diamond \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u0435 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u0440\u0430\u0442\u0430\u0445 \u043d\u0430 \u0433\u0430\u0437. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0433\u0440\u0430\u043d\u0438(facets) \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0437\u0430\u043c\u0435\u043d\u0430\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c DAO \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<h2>\u0422\u0435\u043e\u0440\u0438\u044f<\/h2>\n<p>Diamond \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0432\u043e\u0438\u0445 \u0433\u0440\u0430\u043d\u0435\u0439(facet), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f delegatecall, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 delegatecall, \u043c\u0438\u043b\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0448\u0443: <a href=\"https:\/\/solidity-by-example.org\/delegatecall\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/delegatecall<\/a>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a Diamond \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0430\u0434\u0440\u0435\u0441 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 fallback. \u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f fallback: <a href=\"https:\/\/solidity-by-example.org\/fallback\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/fallback<\/a>.<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fallback \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0432\u044b\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0431\u0430\u0439\u0442\u043e\u0432 \u0438\u0437 msg.data, \u0438\u043b\u0438 \u0436\u0435 \u044d\u0442\u0438 4 \u0431\u0430\u0439\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0432\u0448\u0438\u0441\u044c \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 msg.sig, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0442\u043e\u043c \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c: <a href=\"https:\/\/solidity-by-example.org\/function-selector\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/function-selector<\/a>.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c fallback \u0438 delegatecall, Diamond \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0440\u0430\u043d\u0438(facet), \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0431\u044b \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0432 \u0441\u0430\u043c\u043e\u043c Diamond. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438(\u0447\u0438\u0442\u0430\u0439 \u0433\u0440\u0430\u043d\u0438) \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f delegatecall \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f msg.sender \u0438 msg.value \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 diamond, \u0442\u043e \u0435\u0441\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0433\u0440\u0430\u043d\u044c(facet), \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c diamond.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fallback() \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 diamond:<\/p>\n<pre><code>fallback() external payable {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d \u0432\u044b\u0437\u043e\u0432   address facet = selectorTofacet[msg.sig]; \/\/ \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u0433\u0440\u0430\u043d\u044c \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 mapping selectorTofacet   require(facet != address(0)); \/\/ \u0432\u044b\u043f\u043e\u043b\u044f\u043d\u044f\u0435\u043c \u0432\u044b\u0437\u043e\u0432 external \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u0433\u0440\u0430\u043d\u0438 \u0447\u0435\u0440\u0435\u0437 delegatecall \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \/\/ \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   assembly {     \/\/ \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b     calldatacopy(0, 0, calldatasize()) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0433\u0440\u0430\u043d\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0430\u0434\u0440\u0435\u0441 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043d\u0438         let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)     \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     returndatacopy(0, 0, returndatasize())     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043b\u0438\u0431\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043b\u0438\u0431\u043e \u043e\u0442\u0432\u0435\u0442 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f result     switch result       case 0 {revert(0, returndatasize())}       default {return (0, returndatasize())}   } }<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433\u0438 \u043f\u043e \u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e Diamond:  <\/p>\n<ol>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f fallback.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430 \u0432\u044b\u0437\u043e\u0432 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0443\u0436\u043d\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u043e\u043c\u0443 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 Diamond, \u043d\u0430 \u0433\u0440\u0430\u043d\u044f\u0445(facets) \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u0433\u0438\u043a\u0430.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/49c\/e9c\/a37\/49ce9ca37f92e4074f49cf8818c3298e.png\" alt=\"\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 Diamond\" title=\"\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 Diamond\" width=\"554\" height=\"725\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/49c\/e9c\/a37\/49ce9ca37f92e4074f49cf8818c3298e.png\"\/><figcaption>\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 Diamond<\/figcaption><\/figure>\n<h2>\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430  <\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435\u0439 \u043d\u0435\u043e\u0433\u0440\u0430\u0433\u0438\u0447\u0435\u043d\u043d\u043e, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0427\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435 \u043d\u0435 \u043f\u0435\u0440\u043f\u0443\u0442\u0430\u043b\u0438\u0441\u044c \u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0445\u0430\u043e\u0442\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0442\u043e\u0440\u0430\u0434\u0436 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430, \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0435\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u042d\u0442\u0438 \u0433\u0440\u0430\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0437 \u0441\u0435\u0431\u044f \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 ERC-721.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  \/\/ \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 library LibERC721 { \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430     bytes32 constant ERC721_POSITION = keccak256(\"erc721.storage\");   \/\/ \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f      struct ERC721Storage {         \/\/ tokenId => owner         mapping (uint256 => address) tokenIdToOwner;         \/\/ owner => count of tokens owned         mapping (address => uint256) ownerToNFTokenCount;         string name;         string symbol;        }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0438\u0437 \u0441\u043b\u043e\u0442\u0430 ERC721_POSITION     function getStorage() internal pure returns (ERC721Storage storage storageStruct) {         bytes32 position = ERC721_POSITION;         assembly {             storageStruct.slot := position         }     }     event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);  \/\/ \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0441\u0442\u044c \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c internal     function transferFrom(address _from, address _to, uint256 _tokenId) internal { \/\/ \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a getStorage, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e storage, \u044d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043e \u0442\u043e\u043c, \/\/ \u0447\u0442\u043e \u043c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u0432\u043d\u043e\u0441\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \/\/ \u0430 \u043d\u0435 \u0432 memory \u0438\u043b\u0438 calldata         ERC721Storage storage erc721Storage = LibERC721.getStorage(); \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e         address tokenOwner = erc721Storage.tokenIdToOwner[_tokenId];         require(tokenOwner == _from);         erc721Storage.tokenIdToOwner[_tokenId] = _to;         erc721Storage.ownerToNFTokenCount[_from]--;         erc721Storage.ownerToNFTokenCount[_to]++;         emit Transfer(_from, _to, _tokenId);     } } \/\/ \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u043e \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435  \/\/ \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442  \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 diamond, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f ERC721_POSITION \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0443, \/\/ \u0430 struct ERC721Storage \u043a\u0430\u043a \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \/\/ \u043a \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond contract ERC721Facet {     function name() external view returns (string memory name_) {         name_ = LibERC721.getStorage().name;     }          function symbol() external view returns (string memory symbol_) {         symbol_ = LibERC721.getStorage().symbol;     }      function transferFrom(address _from, address _to, uint256 _tokenId) external {         LibERC721.transferFrom(_from, _to, _tokenId);     } } \/\/ \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 contract ERC721BatchTransferFacet {     function batchTransferFrom(address _from, address _to, uint256[] calldata _tokenIds) external {         for(uint256 i; i &lt; _tokenIds.length; i++) {           LibERC721.transferFrom(_from, _to, _tokenIds[i]);         }     } }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u043e\u0440\u0430\u0434\u0436:<\/p>\n<ol>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0438\u0445 \u0432 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c mapping, \u043f\u043e\u043c\u0435\u0449\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043c\u0435\u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b, \u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u0435, \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0433\u0440\u0430\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u0438\u0445 \u0438 \u0442\u0435\u0445 \u0436\u0435 \u043c\u0435\u0441\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0433\u0440\u0430\u043d\u0435\u0439 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0433\u0434\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e, \u043a\u0430\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043d\u0435\u0439\u043c\u0438\u043d\u0433\u0430, \u0442\u0430\u043a \u0438 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430:<\/p>\n<ol>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0438\u043b\u0438 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0451, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u0432\u0430\u0441 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0435\u0441\u0442\u044c mapping, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0442\u0430\u043a\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430, \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f Diamond. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0443\u044e \u043c\u0430\u043f\u0438\u043d\u0433\u043e\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0442\u043e \u0432\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u043f\u0438\u043d\u0433 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Diamond \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043d\u043e\u043c\u0435\u0440 \u0441\u043b\u043e\u0442\u0430(ERC721_POSITION \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435) \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449. \u042d\u0442\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u0414\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438 \u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0441\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0439\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u043a\u0430\u044f-\u043b\u0438\u0431\u043e \u0433\u0440\u0430\u043d\u044c \u043c\u043e\u0433\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>selfdestruct<\/code>. \u041f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 <code>selfdestruct<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0433\u0440\u0430\u043d\u0438 \u0438 \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0439\u0442\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 delegatecall. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>selfdestruct<\/code> \u043c\u043e\u0436\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u043c\u0430\u0437\u043e\u043c, \u0438\u043b\u0438 <code>selfdestruct<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043a\u0441\u0438-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond.<\/p>\n<\/li>\n<\/ol>\n<p>\u0413\u0440\u0430\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0438. \u0413\u0440\u0430\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0433\u0440\u0430\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/edf\/ff5\/b61\/edfff5b614d6d26fca15964d1737ae10.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0430\u043d\u0435\u0439\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0430\u043d\u0435\u0439\" width=\"640\" height=\"360\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/edf\/ff5\/b61\/edfff5b614d6d26fca15964d1737ae10.png\"\/><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0430\u043d\u0435\u0439<\/figcaption><\/figure>\n<p>\u041d\u0430 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435 \u0432\u044b\u0448\u0435:<\/p>\n<ul>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e FacetA \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a DataA<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e FacetB\u00a0\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a DataB<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434 Diamond \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a DataD<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0441\u0442\u0443\u043f \u043a DataAB \u0438\u043c\u0435\u044e\u0442 \u043a\u0430\u043a FacetA \u0442\u0430\u043a \u0438 FacetB<\/p>\n<\/li>\n<li>\n<p>\u041a DataABD \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043e\u0442\u043a\u0443\u0434\u0430 \u0443\u0433\u043e\u0434\u043d\u043e<\/p>\n<\/li>\n<\/ul>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0437\u0430\u043c\u0435\u043d\u0430\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439  <\/h2>\n<p>\u041b\u044e\u0431\u043e\u0439 Diamond \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IDiamond.  <\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  interface IDiamond { \/\/ \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043a \u0433\u0440\u0430\u043d\u0438 \u0438 \u0435\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c     enum FacetCutAction {Add, Replace, Remove}     \/\/ Add=0, Replace=1, Remove=2 (\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c, \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c, \u0443\u0434\u0430\u043b\u0438\u0442\u044c)  \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0438     struct FacetCut {         address facetAddress; \/\/ \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438         FacetCutAction action; \/\/ \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435         bytes4[] functionSelectors; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439     }  \/\/ \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437,  \/\/ \u043a\u043e\u0433\u0434\u0430 \u0433\u0440\u0430\u043d\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f, \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f     event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }<\/code><\/pre>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IDiamond \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c IDiamondCut, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e diamondCut.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { IDiamond } from \".\/IDiamond.sol\";  interface IDiamondCut is IDiamond {     \/\/ _diamondCut - \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438, \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \/\/ _init - \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 _calldata \/\/ \u0432 \u043a\u043e\u043d\u0446\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamondCut     function diamondCut(         FacetCut[] calldata _diamondCut,         address _init,         bytes calldata _calldata     ) external;     }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f\u00a0diamondCut \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0444\u0430\u0441\u0435\u0442\u043e\u0432 \u0437\u0430 \u043e\u0434\u043d\u0443 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e.\u00a0\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u0445, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f\/\u0437\u0430\u043c\u0435\u043d\u044b\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439\u00a0\u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 _calldata \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 _init \u0447\u0435\u0440\u0435\u0437 delegatecall.\u00a0\u042d\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u0438\u043b\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0437\u0430\u043c\u0435\u043d\u044b \u0438\/\u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u044e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0415\u0441\u043b\u0438\u00a0\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 _init \u0440\u0430\u0432\u043d\u043e \u043d\u0443\u043b\u0435\u0432\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443\u00a0address(0) \u0442\u043e\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 _calldata \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f.\u00a0\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u00a0_calldata \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c 0 \u0431\u0430\u0439\u0442 \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043d\u0430 etherscan \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 DiamondCut.<\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/h2>\n<p>Diamond \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0443\u0442\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IDiamondLoupe.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  interface IDiamondLoupe {     \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0433\u0440\u0430\u043d\u0438     struct Facet {         address facetAddress; \/\/ \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438         bytes4[] functionSelectors; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438     }      \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0432\u0441\u0435\u043c \u0433\u0440\u0430\u043d\u044f\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c Diamond     function facets() external view returns (Facet[] memory facets_);      \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u0441\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0433\u0440\u0430\u043d\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 Diamond     function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);      \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0432\u0441\u0435\u0445 \u0433\u0440\u0430\u043d\u0435\u0439     function facetAddresses() external view returns (address[] memory facetAddresses_);      \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0433\u0440\u0430\u043d\u0438 \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043d\u0438     function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_); }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 IDiamondCut \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c Diamond, \u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e IDiamondLoupe \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438 \u0438 \u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432.<\/p>\n<h2>\u041f\u0440\u0430\u043a\u0442\u0438\u043a\u0430<\/h2>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 erc20 \u0432\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0431\u0438\u0442 \u043d\u0430 4 \u0433\u0440\u0430\u043d\u0438. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u0430\u0434\u043d\u043e\u0441\u0442\u0438, \u0432\u0435\u0434\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 erc20 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0432\u0441\u0435\u043c \u0438\u043b\u0438 \u043c\u043d\u043e\u0433\u0438\u043c.<\/p>\n<p>\u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u043c\u0438 \u0433\u0440\u0430\u043d\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0443\u0436\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u042d\u0442\u0438 \u0446\u0435\u043b\u044f\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 LibDiamond \u0438 \u0442\u0440\u0438 \u0433\u0440\u0430\u043d\u0438: DiamondCutFacet &#8212; \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, DiamondLoupeFacet &#8212; \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond, OwnershipFacet &#8212; \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamindCut, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043d\u0435 \u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043a\u0435\u043c \u043f\u043e\u043f\u0430\u043b\u043e.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 LibDiamond, \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0430\u043d\u0430 \u0432 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043d\u0430 github:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { IDiamond } from \"..\/interfaces\/IDiamond.sol\"; import { IDiamondCut } from \"..\/interfaces\/IDiamondCut.sol\";  library LibDiamond { \/\/ \u043d\u043e\u043c\u0435\u0440 \u0441\u043b\u043e\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f DiamondStorage     bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"diamond.standard.diamond.storage\");      struct FacetAddressAndSelectorPosition {         address facetAddress; \/\/ \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438         uint16 selectorPosition; \/\/ \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 bytes4[] selectors     }      struct DiamondStorage {         \/\/ \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0432\u0438\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 => \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u043c\u0443         mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438         bytes4[] selectors;         \/\/ \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 Diamond, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c diamondCut         address contractOwner;     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443     function diamondStorage() internal pure returns (DiamondStorage storage ds) {         bytes32 position = DIAMOND_STORAGE_POSITION;         assembly {             ds.slot := position         }     }      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);  \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430     function setContractOwner(address _newOwner) internal {         DiamondStorage storage ds = diamondStorage();         address previousOwner = ds.contractOwner;         ds.contractOwner = _newOwner;         emit OwnershipTransferred(previousOwner, _newOwner);     }  \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430     function contractOwner() internal view returns (address contractOwner_) {         contractOwner_ = diamondStorage().contractOwner;     }  \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043b\u0434\u0430\u0435\u043b\u044c\u0446\u0435\u043c Diamond     function enforceIsContractOwner() internal view {         if(msg.sender != diamondStorage().contractOwner) {             revert NotContractOwner(msg.sender, diamondStorage().contractOwner);         }             }      event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);      \/\/ \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b Diamond     function diamondCut(         IDiamondCut.FacetCut[] memory _diamondCut,         address _init,         bytes memory _calldata     ) internal {         for (uint256 facetIndex; facetIndex &lt; _diamondCut.length; facetIndex++) {             bytes4[] memory functionSelectors = _diamondCut[facetIndex].functionSelectors;             address facetAddress = _diamondCut[facetIndex].facetAddress;             if(functionSelectors.length == 0) {                 revert NoSelectorsProvidedForFacetForCut(facetAddress);             }             IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;             if (action == IDiamond.FacetCutAction.Add) {                 addFunctions(facetAddress, functionSelectors);             } else if (action == IDiamond.FacetCutAction.Replace) {                 replaceFunctions(facetAddress, functionSelectors);             } else if (action == IDiamond.FacetCutAction.Remove) {                 removeFunctions(facetAddress, functionSelectors);             } else {                 revert IncorrectFacetCutAction(uint8(action));             }         }         emit DiamondCut(_diamondCut, _init, _calldata);         initializeDiamondCut(_init, _calldata);     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f\/\u0437\u0430\u043c\u0435\u043d\u044b\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438\u0437 \u0433\u0440\u0430\u043d\u0435\u0439     function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {                      }     function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {                      }     function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {                            }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0432 \u043a\u043e\u043d\u0446\u0435 diamondCut, \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445     function initializeDiamondCut(address _init, bytes memory _calldata) internal {         if (_init == address(0)) {             return;         }         enforceHasContractCode(_init, \"LibDiamondCut: _init address has no code\");                 (bool success, bytes memory error) = _init.delegatecall(_calldata);         if (!success) {             if (error.length > 0) {                 \/\/ bubble up error                 \/\/\/ @solidity memory-safe-assembly                 assembly {                     let returndata_size := mload(error)                     revert(add(32, error), returndata_size)                 }             } else {                 revert InitializationFunctionReverted(_init, _calldata);             }         }             }  \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0430\u0434\u0440\u0435\u0441 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c, \u0430 \u043d\u0435 \u0430\u0434\u0440\u0435\u0441\u043e\u043c     function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {         uint256 contractSize;         assembly {             contractSize := extcodesize(_contract)         }         if(contractSize == 0) {             revert NoBytecodeAtAddress(_contract, _errorMessage);         }             } }<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u0440\u0430\u043d\u044c DiamondCutFacet, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0430\u044f \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 Diamond:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { IDiamondCut } from \"..\/interfaces\/IDiamondCut.sol\"; \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u0439 \u0438 \u043c\u0435\u043d\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 import { LibDiamond } from \"..\/libraries\/LibDiamond.sol\";  contract DiamondCutFacet is IDiamondCut {          function diamondCut(         FacetCut[] calldata _diamondCut,         address _init,         bytes calldata _calldata     ) external override { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u044f\u0432\u043b\u044f\u0435\u0438\u0441\u044f \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c Diamind         LibDiamond.enforceIsContractOwner(); \/\/ \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c diamondCut \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438         LibDiamond.diamondCut(_diamondCut, _init, _calldata);     } }<\/code><\/pre>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u0440\u0430\u043d\u044c DiamondLoupeFacet, \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0432 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 github:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { LibDiamond } from  \"..\/libraries\/LibDiamond.sol\"; import { IDiamondLoupe } from \"..\/interfaces\/IDiamondLoupe.sol\";  contract DiamondLoupeFacet is IDiamondLoupe {      \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0432\u0441\u0435\u043c \u0433\u0440\u0430\u043d\u044f\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c Diamond     function facets() external override view returns (Facet[] memory facets_) {         \/\/ \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     }  \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0432\u0441\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0433\u0440\u0430\u043d\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 Diamond     function facetFunctionSelectors(address _facet) external override view returns (bytes4[] memory _facetFunctionSelectors) {         \/\/ \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     }  \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0432\u0441\u0435\u0445 \u0433\u0440\u0430\u043d\u0435\u0439     function facetAddresses() external override view returns (address[] memory facetAddresses_) {         \/\/ \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     }  \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0433\u0440\u0430\u043d\u0438 \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043d\u0438     function facetAddress(bytes4 _functionSelector) external override view returns (address facetAddress_) {         \/\/ \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0430\u043d\u044c OwnershipFacet:  <\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { LibDiamond } from \"..\/libraries\/LibDiamond.sol\";  contract OwnershipFacet { \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043f\u0440\u0430\u0432\u0430 \u0432\u043b\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u0430 Diamond \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443     function transferOwnership(address _newOwner) external { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 Diamond         LibDiamond.enforceIsContractOwner(); \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430         LibDiamond.setContractOwner(_newOwner);     }  \/\/ view \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 Diamond     function owner() external view returns (address owner_) {         owner_ = LibDiamond.contractOwner();     } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 Diamond, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0439\u043c\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438 \u0432 \u043a\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c Diamond \u0438 \u0433\u0440\u0430\u043d\u0438.<\/p>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 Diamond:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { LibDiamond } from \".\/libraries\/LibDiamond.sol\"; import { IDiamondCut } from \".\/interfaces\/IDiamondCut.sol\";  error FunctionNotFound(bytes4 _functionSelector);  struct DiamondArgs {     address owner;     address init;     bytes initCalldata; }  contract Diamond {          constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable {         LibDiamond.setContractOwner(_args.owner);         LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434  \/\/ \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435     }      fallback() external payable { \/\/ \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430         LibDiamond.DiamondStorage storage ds;         bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;         \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u0443\u043a\u0430\u0437\u0430\u0432 \u0441\u043b\u043e\u0442, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f         assembly {             ds.slot := position         }         \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438 \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438         address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress; \/\/ \u0435\u0441\u043b\u0438 \u0433\u0440\u0430\u043d\u044c \u043d\u0435 \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443         if(facet == address(0)) {              revert FunctionNotFound(msg.sig);         }         \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u0433\u0440\u0430\u043d\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0437\u0430\u0434 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         assembly {             calldatacopy(0, 0, calldatasize())             let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)             returndatacopy(0, 0, returndatasize())             switch result                 case 0 {                     revert(0, returndatasize())                 }                 default {                     return(0, returndatasize())                 }         }     }      receive() external payable {} }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043d\u0430 github.<\/p>\n<pre><code class=\"typescript\">let diamondCutFacet: DiamondCutFacet; let diamondLoupeFacet: DiamondLoupeFacet; let ownershipFacet: OwnershipFacet; let constantsFacet: ConstantsFacet; let balancesFacet: BalancesFacet; let allowancesFacet: AllowancesFacet; let supplyRegulatorFacet: SupplyRegulatorFacet;  interface FacetCut {     facetAddress: string,     action: FacetCutAction,     functionSelectors: string[] }  interface FacetToAddress {     [key: string]: string }  let diamondInit: DiamondInit;  let owner: SignerWithAddress, admin: SignerWithAddress,  user1: SignerWithAddress, user2: SignerWithAddress, user3: SignerWithAddress;  const totalSupply = parseEther('100000'); const transferAmount = parseEther('1000'); const name = \"Token Name\"; const symbol = \"SYMBOL\"; const decimals = 18;  beforeEach(async () => {     [owner, admin, user1, user2, user3] = await ethers.getSigners(); });  enum FacetCutAction {     Add,     Replace,     Remove }  let calldataAfterDeploy: string; let addressDiamond: string;  let facetToAddressImplementation: FacetToAddress = {};  \/\/ \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u043e \u0447\u0430\u0441\u0442\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u043e\u0432 let facetCuts: FacetCut[] = [];  \/\/ \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0433\u0440\u0430\u043d\u0438 \u0438 \u0441\u0430\u043c Diamond  const FacetNames = [     'DiamondCutFacet',     'DiamondLoupeFacet',     'OwnershipFacet' ]; \/\/ \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0435\u043f\u043b\u043e\u0438\u043c \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0433\u0440\u0430\u043d\u0438, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 Diamond \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a Diamond \/\/ \u0435\u0441\u043b\u0438 \u044d\u0442\u0438 \u0433\u0440\u0430\u043d\u0438 \u0443\u0436\u0435 \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0435\u043d\u044b, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0433\u0440\u0430\u043d\u0435\u0439 \u0434\u043b\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f Diamond\", async function() {     for (const FacetName of FacetNames) {         const Facet = await ethers.getContractFactory(FacetName)         const facet = await Facet.deploy()         await facet.deployed(); \/\/ \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435(\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c) \u0438 \/\/ \u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0445\u0435\u043b\u043f\u0435\u0440\u0430 \/\/ \u043a\u043e\u0434 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0430 github         facetCuts.push({           facetAddress: facet.address,           action: FacetCutAction.Add,           functionSelectors: getSelectors(facet)         }); \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0433\u0440\u0430\u043d\u0438 \u0438 \u0430\u0434\u0440\u0435\u0441, \u043a\u0443\u0434\u0430 \u0433\u0440\u0430\u043d\u044c \u0431\u044b\u0434\u0430 \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0435\u043d\u0430         facetToAddressImplementation[FacetName] = facet.address;     }; });  \/\/ \u0434\u0435\u043f\u043b\u043e\u0439 Diamond, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438 facetCuts \/\/ \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 diamondArgs mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond\", async function () {     const diamondArgs = {         owner: owner.address, \/\/ \u0430\u0434\u0440\u0435\u0441 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438         init: ethers.constants.AddressZero, \/\/ \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c         initCalldata: '0x00' \/\/ \u043f\u0443\u0441\u0442\u0430\u044f \u043a\u043e\u043b\u043b\u0434\u0430\u0442\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438     };     const Diamond = await ethers.getContractFactory('Diamond')     const diamond = await Diamond.deploy(facetCuts, diamondArgs)     await diamond.deployed();     addressDiamond = diamond.address; });  \/\/ \u0441\u043e\u0437\u0430\u0434\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432, \u043d\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u043c Diamond, \/\/ \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 mocha.step(\"\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432\", async function () {     diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', addressDiamond);     diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', addressDiamond);     ownershipFacet = await ethers.getContractAt('OwnershipFacet', addressDiamond); });  \/\/ \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u0445 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u0433\u0440\u0430\u043d\u0438 DiamondLoupeFacet,  \/\/ \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0433\u0440\u0430\u043d\u0438 \u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0438 \u0447\u0442\u043e \u0441\u0430\u043c\u0430 \u0433\u0440\u0430\u043d\u044c DiamondLoupeFacet \/\/ \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e mocha.step(\"\u0423\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0434\u0440\u0435\u0441\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0441 \u0442\u0435\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u043f\u0440\u0438 \u0434\u0435\u043f\u043b\u043e\u0435 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439\", async function () {     const addresses = [];     for (const address of await diamondLoupeFacet.facetAddresses()) {         addresses.push(address)     }     assert.sameMembers(Object.values(facetToAddressImplementation), addresses) });  mocha.step(\"\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0430\u043c \u0438\u0445 \u0433\u0440\u0430\u043d\u0435\u0439\", async function () {     let selectors = getSelectors(diamondCutFacet)     let result = await diamondLoupeFacet.facetFunctionSelectors(facetToAddressImplementation['DiamondCutFacet'])     assert.sameMembers(result, selectors)     selectors = getSelectors(diamondLoupeFacet)     result = await diamondLoupeFacet.facetFunctionSelectors(facetToAddressImplementation['DiamondLoupeFacet'])     assert.sameMembers(result, selectors)     selectors = getSelectors(ownershipFacet)     result = await diamondLoupeFacet.facetFunctionSelectors(facetToAddressImplementation['OwnershipFacet'])     assert.sameMembers(result, selectors) });  mocha.step(\"\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0430\u0434\u0440\u0435\u0441\u0430 \u0433\u0440\u0430\u043d\u0435\u0439 \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430\u043c, \u043a\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u044d\u0442\u0438\u043c \u0433\u0440\u0430\u043d\u044f\u043c\", async function () {     assert.equal(         facetToAddressImplementation['DiamondCutFacet'],         await diamondLoupeFacet.facetAddress('0x1f931c1c') \/\/diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata)     )     assert.equal(         facetToAddressImplementation['DiamondLoupeFacet'],         await diamondLoupeFacet.facetAddress('0x7a0ed627') \/\/ facets()     )     assert.equal(         facetToAddressImplementation['DiamondLoupeFacet'],         await diamondLoupeFacet.facetAddress('0xadfca15e') \/\/ facetFunctionSelectors(address _facet)     )     assert.equal(         facetToAddressImplementation['OwnershipFacet'],         await diamondLoupeFacet.facetAddress('0xf2fde38b') \/\/ transferOwnership(address _newOwner)     ) });  mocha.step(\"\u0422\u0440\u0430\u043d\u0441\u0444\u0435\u0440 \u043f\u0440\u0430\u0432\u0430 \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\", async function () {     await ownershipFacet.connect(owner).transferOwnership(admin.address);     assert.equal(await ownershipFacet.owner(), admin.address);     await ownershipFacet.connect(admin).transferOwnership(owner.address);     assert.equal(await ownershipFacet.owner(), owner.address); });<\/code><\/pre>\n<p>\u041c\u044b \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c Diamond, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0430 Diamond \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u043e\u043a\u0435\u043d\u0430 ERC20, \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0441\u0443\u0449\u0438 \u044d\u0442\u043e\u043c\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443.<\/p>\n<p>\u0412\u0441\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0431\u0438\u0442\u043e \u043d\u0430 \u0442\u0440\u0438 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f 4 \u0433\u0440\u0430\u043d\u0438, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0433\u0440\u0430\u043d\u0435\u0439 \u0438 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435\u0439 \u043d\u0430 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/38c\/cba\/803\/38ccba803d743f3a4ef96f5c3d841d52.jpg\" alt=\"\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 ERC20 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e Diamond\" title=\"\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 ERC20 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e Diamond\" width=\"4448\" height=\"2567\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/38c\/cba\/803\/38ccba803d743f3a4ef96f5c3d841d52.jpg\" data-blurred=\"true\"\/><figcaption>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 ERC20 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e Diamond<\/figcaption><\/figure>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 LibConstants \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442 \u0442\u043e\u043a\u0435\u043d\u0430, \u043a\u0430\u043a name, symbol, decimals \u0438 \u0430\u0434\u0440\u0435\u0441 \u0430\u0434\u043c\u0438\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 mint(), burn() \u0438\u0437 \u0433\u0440\u0430\u043d\u0438 SupplyRegulatorFacet.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  error NotTokenAdmin();  library LibConstants { \/\/ \u0441\u043b\u043e\u0442, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a ConstantsStates     bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"erc20.constants\");      event AdminshipTransferred(address indexed previousAdmin, address indexed newAdmin);  \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \"erc20.constants\"     struct ConstantsStates {         string name;         string symbol;         uint8 decimals;         address admin;     }      function diamondStorage() internal pure returns (ConstantsStates storage ds) {         bytes32 position = DIAMOND_STORAGE_POSITION;         assembly {             ds.slot := position         }     }  \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u043c\u0438\u043d\u043e\u043c     function enforceIsTokenAdmin() internal view {         if(msg.sender != diamondStorage().admin) {             revert NotTokenAdmin();         }             }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0430     function setTokenAdmin(address _newAdmin) internal {         ConstantsStates storage ds = diamondStorage();         address previousAdmin = ds.admin;         ds.admin = _newAdmin;         emit AdminshipTransferred(previousAdmin, _newAdmin);     } }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 LibBalances \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u043e\u0432 \u0438 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  library LibBalances { \/\/ \u0441\u043b\u043e\u0442, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a BalancesStates     bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"erc20.balances\");      event Transfer(address indexed from, address indexed to, uint256 value);  \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \"erc20.balances\"     struct BalancesStates {         mapping(address => uint256) balances;         uint256 totalSupply;     }      function diamondStorage() internal pure returns (BalancesStates storage ds) {         bytes32 position = DIAMOND_STORAGE_POSITION;         assembly {             ds.slot := position         }      }  \/\/ \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 transfer, mint, burn, \u0432\u0437\u044f\u0442\u044b\u0435 \u043f\u0440\u044f\u043c\u0438\u043a\u043e\u043c \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 erc20 \u043e\u0442 openzeppelin     function transfer(         address from,         address to,         uint256 amount     ) internal {         BalancesStates storage ds = diamondStorage();         require(from != address(0), \"ERC20: transfer from the zero address\");         require(to != address(0), \"ERC20: transfer to the zero address\");          uint256 fromBalance = ds.balances[from];         require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");         unchecked {             ds.balances[from] = fromBalance - amount;             ds.balances[to] += amount;         }         emit Transfer(from, to, amount);     }      function mint(address account, uint256 amount) internal {         BalancesStates storage ds = diamondStorage();         require(account != address(0), \"ERC20: mint to the zero address\");         ds.totalSupply += amount;         unchecked {             ds.balances[account] += amount;         }         emit Transfer(address(0), account, amount);     }      function burn(address account, uint256 amount) internal {         BalancesStates storage ds = diamondStorage();         require(account != address(0), \"ERC20: burn from the zero address\");         uint256 accountBalance = ds.balances[account];         require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");         unchecked {             ds.balances[account] = accountBalance - amount;             ds.totalSupply -= amount;         }         emit Transfer(account, address(0), amount);     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 LibConstants \u043d\u0443\u0436\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0438 \u0432 Diamond.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  \/\/ \u0438\u043c\u043f\u043e\u0440\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c import { LibConstants } from \"..\/libraries\/LibConstants.sol\"; import { LibBalances } from \"..\/libraries\/LibBalances.sol\";  contract DiamondInit {     \/\/ \u0444\u0443\u043d\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445     function initERC20(string calldata _name, string calldata _symbol, uint8 _decimals, address _admin, uint256 _totalSupply) external {         LibConstants.ConstantsStates storage constantsStorage = LibConstants.diamondStorage(); \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:         constantsStorage.name = _name;         constantsStorage.symbol = _symbol;         constantsStorage.decimals = _decimals;         constantsStorage.admin = _admin; \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435         LibBalances.mint(_admin, _totalSupply);     } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0433\u0440\u0430\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 LibConstants:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { LibConstants } from \"..\/libraries\/LibConstants.sol\";  contract ConstantsFacet {  \/\/ \u043e\u0431\u044b\u0447\u043d\u044b\u0435 view \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u0441\u0443\u0449\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 ERC20: name, symbol, decimals     function name() external view returns (string memory) {         LibConstants.ConstantsStates storage ds = LibConstants.diamondStorage();         return ds.name;     }      function symbol() external view returns (string memory) {         LibConstants.ConstantsStates storage ds = LibConstants.diamondStorage();         return ds.symbol;     }      function decimals() external view returns (uint8) {         LibConstants.ConstantsStates storage ds = LibConstants.diamondStorage();         return ds.decimals;     }  \/\/ \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0430     function admin() external view returns (address) {         LibConstants.ConstantsStates storage ds = LibConstants.diamondStorage();         return ds.admin;     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0430\u0434\u043c\u0438\u043d\u0441\u043a\u0438\u0445 \u043f\u0440\u0430\u0432 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d     function transferAdminship(address _newAdmin) external { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u044d\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0430\u0434\u043c\u0438\u043d         LibConstants.enforceIsTokenAdmin(); \/\/\u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0430         LibConstants.setTokenAdmin(_newAdmin);     }  }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0432 \u0445\u043e\u0434\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 initERC20 \u0438\u0437 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 DiamondInit, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0433\u0440\u0430\u043d\u044c ConstantsFacet:<\/p>\n<pre><code class=\"typescript\">mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 name(), symbol() \u0438 \u0442. \u0434. \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamondCut\", async function() {     const DiamondInit = await ethers.getContractFactory('DiamondInit');     diamondInit = await DiamondInit.deploy();     await diamondInit.deployed(); });  mocha.step(\"\u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 calldata, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u0438\u0437 Diamond \u0447\u0435\u0440\u0435\u0437 delegatecall \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamondCut\", async function () { \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 initERC20     calldataAfterDeploy = diamondInit.interface.encodeFunctionData('initERC20', [         name,         symbol,         decimals,         admin.address,         totalSupply     ]); });  mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438(\u0433\u0440\u0430\u043d\u0438) \u0441 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438\", async function () {     const ConstantsFacet = await ethers.getContractFactory(\"ConstantsFacet\");     const constantsFacet = await ConstantsFacet.deploy();     constantsFacet.deployed();     const facetCuts = [{         facetAddress: constantsFacet.address,         action: FacetCutAction.Add,         functionSelectors: getSelectors(constantsFacet)     }]; \/\/ \u0434\u0432\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430: \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u043b\u0434\u0430\u0442\u0430 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0435\u0441\u0442\u044c \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f     await diamondCutFacet.connect(owner).diamondCut(facetCuts, diamondInit.address, calldataAfterDeploy);     facetToAddressImplementation['ConstantsFacet'] = constantsFacet.address; });  \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435 \u0430\u0434\u0440\u0435\u0441 Diamond, \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 mocha.step(\"\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438\", async function () {     constantsFacet = await ethers.getContractAt('ConstantsFacet', addressDiamond); });  mocha.step(\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435\", async function () {     assert.equal(await constantsFacet.name(), \"Token Name\");     assert.equal(await constantsFacet.symbol(), symbol);     assert.equal(await constantsFacet.decimals(), decimals);     assert.equal(await constantsFacet.admin(), admin.address); });<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0433\u0440\u0430\u043d\u044c \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e transfer \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u043c \u0430\u0434\u0440\u0435\u0441\u0430\u043c.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  import { LibBalances } from \"..\/libraries\/LibBalances.sol\";  contract BalancesFacet { \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 erc20:     function totalSupply() external view returns (uint256) {         LibBalances.BalancesStates storage ds = LibBalances.diamondStorage();         return ds.totalSupply;     }      function balanceOf(address _account) external view returns (uint256) {         LibBalances.BalancesStates storage ds = LibBalances.diamondStorage();         return ds.balances[_account];     }      function transfer(address _to, uint256 _amount) external returns (bool) {         address owner = msg.sender;         LibBalances.transfer(owner, _to, _amount);         return true;     } }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0445\u043e\u0434\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0433\u0440\u0430\u043d\u044c BalancesFacet:<\/p>\n<pre><code class=\"typescript\">\/\/ \u0434\u0435\u043f\u043b\u043e\u0439 \u0433\u0440\u0430\u043d\u0438 BalancesFacet mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0430\", async function () {     const BalancesFacet = await ethers.getContractFactory(\"BalancesFacet\");     const balancesFacet = await BalancesFacet.deploy();     balancesFacet.deployed();     const facetCuts = [{         facetAddress: balancesFacet.address,         action: FacetCutAction.Add,         functionSelectors: getSelectors(balancesFacet)     }]; \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u043d\u0438 \u0432 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442     await diamondCutFacet.connect(owner).diamondCut(facetCuts, ethers.constants.AddressZero, \"0x00\");     facetToAddressImplementation['BalancesFacet'] = balancesFacet.address; });  \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0443 \u0430\u0434\u0440\u0435\u0441 Diamond \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 mocha.step(\"\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 c \u0431\u0430\u043b\u0430\u043d\u0441\u0430\u043c\u0438 \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u043e\u043c\", async function () {     balancesFacet = await ethers.getContractAt('BalancesFacet', addressDiamond); });  \/\/ \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u0433\u0440\u0430\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 mocha.step(\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 view \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441 \u0431\u0430\u043b\u0430\u043d\u0441\u0430\u043c\u0438 \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u043e\u043c\", async function () {     expect(await balancesFacet.totalSupply()).to.be.equal(totalSupply);     expect(await balancesFacet.balanceOf(admin.address)).to.be.equal(totalSupply); });  mocha.step(\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0430\", async function () {     await balancesFacet.connect(admin).transfer(user1.address, transferAmount);     expect(await balancesFacet.balanceOf(admin.address)).to.be.equal(totalSupply.sub(transferAmount));     expect(await balancesFacet.balanceOf(user1.address)).to.be.equal(transferAmount);     await balancesFacet.connect(user1).transfer(admin.address, transferAmount); });<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0440\u0430\u043d\u044c, \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 erc20, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u043f\u0440\u0443\u0432\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0441 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f transferFrom, \u043f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0439 \u0433\u0440\u0430\u043d\u0438 \u043d\u0430\u043c \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u043a\u0442\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u0443 \u0437\u0430\u0430\u043f\u0440\u0443\u0432\u0438\u043b.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  library LibAllowances { \/\/ \u0441\u043b\u043e\u0442, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a AllowancesStates     bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\"erc20.allowances\");      event Approval(address indexed owner, address indexed spender, uint256 value);  \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \"erc20.allowances\"     struct AllowancesStates {         mapping(address => mapping(address => uint256)) allowances;     }      function diamondStorage() internal pure returns (AllowancesStates storage ds) {         bytes32 position = DIAMOND_STORAGE_POSITION;         assembly {             ds.slot := position         }      }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u043f\u0440\u0443\u0432\u0430     function approve(         address _owner,         address _spender,         uint256 _amount     ) internal {         AllowancesStates storage ds = diamondStorage();         require(_owner != address(0), \"ERC20: approve from the zero address\");         require(_spender != address(0), \"ERC20: approve to the zero address\");          ds.allowances[_owner][_spender] = _amount;         emit Approval(_owner, _spender, _amount);     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u0440\u0430\u0442\u044b \u0437\u0430\u0430\u043f\u0440\u0443\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b     function spendAllowance(         address _owner,         address _spender,         uint256 _amount     ) internal {         AllowancesStates storage ds = diamondStorage();         uint256 currentAllowance = ds.allowances[_owner][_spender];         if (currentAllowance != type(uint256).max) {             require(currentAllowance >= _amount, \"ERC20: insufficient allowance\");             unchecked {                 approve(_owner, _spender, currentAllowance - _amount);             }         }     } }<\/code><\/pre>\n<p> \u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0433\u0440\u0430\u043d\u0438:<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0; \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f import { LibBalances } from \"..\/libraries\/LibBalances.sol\"; import { LibAllowances } from \"..\/libraries\/LibAllowances.sol\";  contract AllowancesFacet { \/\/ \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ERC20 \/\/ view \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0430\u043f\u0440\u0443\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b     function allowance(address _owner, address _spender) external view returns (uint256) {         LibAllowances.AllowancesStates storage ds = LibAllowances.diamondStorage();         return ds.allowances[_owner][_spender];     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0443\u043c\u043c\u044b \u043d\u0430 \u0430\u0434\u0440\u0435\u0441     function approve(address _spender, uint256 _amount) external returns (bool) {         address owner = msg.sender;         LibAllowances.approve(owner, _spender, _amount);         return true;     }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0430 \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b     function transferFrom(         address _from,         address _to,         uint256 _amount     ) external returns (bool) {         address spender = msg.sender;         LibAllowances.spendAllowance(_from, spender, _amount);         LibBalances.transfer(_from, _to, _amount);         return true;     } }<\/code><\/pre>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0433\u0440\u0430\u043d\u044c AllowancesFacet \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043b\u0438 \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0434\u0435\u043f\u043b\u043e\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0433\u0440\u0430\u043d\u0435\u0439:<\/p>\n<pre><code class=\"typescript\">mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441 allowances\", async function () {     const AllowancesFacet = await ethers.getContractFactory(\"AllowancesFacet\");     const allowancesFacet = await AllowancesFacet.deploy();     allowancesFacet.deployed();     const facetCuts = [{         facetAddress: allowancesFacet.address,         action: FacetCutAction.Add,         functionSelectors: getSelectors(allowancesFacet)     }];     await diamondCutFacet.connect(owner).diamondCut(facetCuts, ethers.constants.AddressZero, \"0x00\");     facetToAddressImplementation['ConstantsFacet'] = allowancesFacet.address; });  mocha.step(\"\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 c \u0431\u0430\u043b\u0430\u043d\u0441\u0430\u043c\u0438 \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u043e\u043c allowance, approve, transferFrom \u0438 \u0442. \u0434.\", async function () {     allowancesFacet = await ethers.getContractAt('AllowancesFacet', addressDiamond); });  mocha.step(\"\u0422\u0435\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 allowance, approve, transferFrom\", async function () {     expect(await allowancesFacet.allowance(admin.address, user1.address)).to.equal(0);     const valueForApprove = parseEther(\"100\");     const valueForTransfer = parseEther(\"30\");     await allowancesFacet.connect(admin).approve(user1.address, valueForApprove);     expect(await allowancesFacet.allowance(admin.address, user1.address)).to.equal(valueForApprove);     await allowancesFacet.connect(user1).transferFrom(admin.address, user2.address, valueForTransfer);     expect(await balancesFacet.balanceOf(user2.address)).to.equal(valueForTransfer);     expect(await balancesFacet.balanceOf(admin.address)).to.equal(totalSupply.sub(valueForTransfer));     expect(await allowancesFacet.allowance(admin.address, user1.address)).to.equal(valueForApprove.sub(valueForTransfer)); });<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u043d\u0443 \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u043c\u0438\u0441\u0441\u0438\u044e \u0442\u043e\u043a\u0435\u043d\u0430, \u0432 \u043d\u0435\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: mint \u0438 burn, \u0438\u0445 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0434\u043c\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 initERC20.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0; \/\/ \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0443\u0436\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a import { LibBalances } from \"..\/libraries\/LibBalances.sol\"; import { LibConstants } from \"..\/libraries\/LibConstants.sol\";  contract SupplyRegulatorFacet {          function mint(address _account, uint256 _amount) external {         LibConstants.enforceIsTokenAdmin(); \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0430\u0434\u043c\u0438\u043d         LibBalances.mint(_account, _amount);     }      function burn(address _account, uint256 _amount) external {         LibConstants.enforceIsTokenAdmin(); \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0430\u0434\u043c\u0438\u043d         LibBalances.burn(_account, _amount);      } }<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:<\/p>\n<pre><code class=\"typescript\">mocha.step(\"\u0414\u0435\u043f\u043b\u043e\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441 mint \u0438 burn\", async function () {     const SupplyRegulatorFacet = await ethers.getContractFactory(\"SupplyRegulatorFacet\");     supplyRegulatorFacet = await SupplyRegulatorFacet.deploy();     supplyRegulatorFacet.deployed();     const facetCuts = [{         facetAddress: supplyRegulatorFacet.address,         action: FacetCutAction.Add,         functionSelectors: getSelectors(supplyRegulatorFacet)     }];     await diamondCutFacet.connect(owner).diamondCut(facetCuts, ethers.constants.AddressZero, \"0x00\");     facetToAddressImplementation['SupplyRegulatorFacet'] = supplyRegulatorFacet.address; });  mocha.step(\"\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 mint \u0438 burn\", async function () {     supplyRegulatorFacet = await ethers.getContractAt('SupplyRegulatorFacet', addressDiamond); });  mocha.step(\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 mint \u0438 burn\", async function () {     const mintAmount = parseEther('1000');     const burnAmount = parseEther('500');     await supplyRegulatorFacet.connect(admin).mint(user3.address, mintAmount);     expect(await balancesFacet.balanceOf(user3.address)).to.equal(mintAmount);     expect(await balancesFacet.totalSupply()).to.be.equal(totalSupply.add(mintAmount));     await supplyRegulatorFacet.connect(admin).burn(user3.address, burnAmount);     expect(await balancesFacet.balanceOf(user3.address)).to.equal(mintAmount.sub(burnAmount));     expect(await balancesFacet.totalSupply()).to.be.equal(totalSupply.add(mintAmount).sub(burnAmount)); });<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 ERC20 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u043d\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u041d\u043e, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c Diamond \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043c\u044b \u043f\u0440\u0438\u0448\u043b\u0438 \u043a \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438 \u043d\u0430\u0441 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e diamondCut? \u0414\u043b\u044f \u044d\u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u0430\u043b\u0438\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamondCut:  <\/p>\n<pre><code class=\"typescript\">mocha.step(\"\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 diamondCut \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438\", async function () {     const facetCuts = [{         facetAddress: ethers.constants.AddressZero,         action: FacetCutAction.Remove,         functionSelectors: ['0x1f931c1c'] \/\/diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata)     }];     await diamondCutFacet.connect(owner).diamondCut(facetCuts, ethers.constants.AddressZero, \"0x00\"); });<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u043c \u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u0431\u0443\u0434\u044c\u0442\u0435 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u044b, \u0435\u0441\u043b\u0438 \u0440\u0435\u0448\u0438\u0442\u0435\u0441\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e diamondCut \u0438\u0437 Diamond.<\/p>\n<h2>\u041f\u043e\u0441\u043b\u0435\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e-\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435: <a href=\"https:\/\/www.youtube.com\/watch?v=42TUqDW74v8\" rel=\"noopener noreferrer nofollow\">https:\/\/www.youtube.com\/watch?v=42TUqDW74v8<\/a><\/p>\n<p>GitHub: <a href=\"https:\/\/github.com\/davydovMikhail\/multi-proxy-contract\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/davydovMikhail\/multi-proxy-contract<\/a><\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b? \u0421 \u0447\u0435\u043c-\u0442\u043e \u043d\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u044b? \u041f\u0438\u0448\u0438\u0442\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438<\/p>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0430 \u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0430\u043b\u044e\u0442\u043e\u0439: 0x021Db128ceab47C66419990ad95b3b180dF3f91F<\/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\/post\/709642\/\"> https:\/\/habr.com\/ru\/post\/709642\/<\/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<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=42TUqDW74v8\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e-\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/davydovMikhail\/multi-proxy-contract\" rel=\"noopener noreferrer nofollow\">GitHub<\/a><\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043f\u0440\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 EIP-2535, \u0442\u0430\u043a\u0436\u0435 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043a\u0430\u043a Diamond \u0438\u043b\u0438 Multi-Facet Proxy. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0435, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0441\u043c\u0430\u0440\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u0440\u044f\u0434\u043e\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u043f\u0435\u0440\u0435\u0434 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430\u043c\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u043a\u0430\u043a Transparent \u0438 UUPS.  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u044b, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 Diamond \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:  <\/p>\n<ol>\n<li>\n<p>Diamond \u0438\u043c\u0435\u0435\u0442 \u0435\u0434\u0438\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 proxy \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a\u043e \u0432\u0441\u0435\u043c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u043c, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043c\u0430\u0440\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>Diamond \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u0441\u0435\u0445 \u0432\u0430\u0448\u0438\u0445 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043b\u0435\u043a\u043e \u0437\u0430 24 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0438\u0431\u043a\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0433\u0440\u0430\u043d\u044f\u043c\u0438(facets), \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430\u043c\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0421 \u0442\u0435\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430, \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u0430 \u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0430. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432 \u043f. 2 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043d\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 Diamond \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c, \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443, \u043b\u0438\u0431\u043e \u043f\u043e \u043f\u0440\u043e\u0448\u0435\u0432\u0441\u0442\u0432\u0438\u044e \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c Diamond \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c.<\/p>\n<\/li>\n<li>\n<p>Diamond \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u0435 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u0440\u0430\u0442\u0430\u0445 \u043d\u0430 \u0433\u0430\u0437. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0433\u0440\u0430\u043d\u0438(facets) \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\/\u0437\u0430\u043c\u0435\u043d\u0430\/\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c DAO \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<h2>\u0422\u0435\u043e\u0440\u0438\u044f<\/h2>\n<p>Diamond \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0432\u043e\u0438\u0445 \u0433\u0440\u0430\u043d\u0435\u0439(facet), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f delegatecall, \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u0443-\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 delegatecall, \u043c\u0438\u043b\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0448\u0443: <a href=\"https:\/\/solidity-by-example.org\/delegatecall\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/delegatecall<\/a>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a Diamond \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0430\u0434\u0440\u0435\u0441 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 fallback. \u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f fallback: <a href=\"https:\/\/solidity-by-example.org\/fallback\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/fallback<\/a>.<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fallback \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0432\u044b\u0445 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0431\u0430\u0439\u0442\u043e\u0432 \u0438\u0437 msg.data, \u0438\u043b\u0438 \u0436\u0435 \u044d\u0442\u0438 4 \u0431\u0430\u0439\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0432\u0448\u0438\u0441\u044c \u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 msg.sig, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0442\u043e\u043c \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u0430\u043a \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c: <a href=\"https:\/\/solidity-by-example.org\/function-selector\/\" rel=\"noopener noreferrer nofollow\">solidity-by-example\/function-selector<\/a>.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c fallback \u0438 delegatecall, Diamond \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0440\u0430\u043d\u0438(facet), \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0431\u044b \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0432 \u0441\u0430\u043c\u043e\u043c Diamond. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438(\u0447\u0438\u0442\u0430\u0439 \u0433\u0440\u0430\u043d\u0438) \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f delegatecall \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f msg.sender \u0438 msg.value \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 diamond, \u0442\u043e \u0435\u0441\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0433\u0440\u0430\u043d\u044c(facet), \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0434\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u043c diamond.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fallback() \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 diamond:<\/p>\n<pre><code>fallback() external payable {   \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d \u0432\u044b\u0437\u043e\u0432   address facet = selectorTofacet[msg.sig]; \/\/ \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u0433\u0440\u0430\u043d\u044c \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 mapping selectorTofacet   require(facet != address(0)); \/\/ \u0432\u044b\u043f\u043e\u043b\u044f\u043d\u044f\u0435\u043c \u0432\u044b\u0437\u043e\u0432 external \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u0433\u0440\u0430\u043d\u0438 \u0447\u0435\u0440\u0435\u0437 delegatecall \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \/\/ \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   assembly {     \/\/ \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b     calldatacopy(0, 0, calldatasize()) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0433\u0440\u0430\u043d\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0430\u0434\u0440\u0435\u0441 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043d\u0438         let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)     \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     returndatacopy(0, 0, returndatasize())     \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043b\u0438\u0431\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043b\u0438\u0431\u043e \u043e\u0442\u0432\u0435\u0442 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f result     switch result       case 0 {revert(0, returndatasize())}       default {return (0, returndatasize())}   } }<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433\u0438 \u043f\u043e \u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e Diamond:  <\/p>\n<ol>\n<li>\n<p>\u0412 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f fallback.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430 \u0432\u044b\u0437\u043e\u0432 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0443\u0436\u043d\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u043e\u043c\u0443 \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u0433\u0440\u0430\u043d\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 Diamond, \u043d\u0430 \u0433\u0440\u0430\u043d\u044f\u0445(facets) \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u0433\u0438\u043a\u0430.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"bordered full-width\"><figcaption>\u0421\u0442\u0440\u043e\u0435\u043d\u0438\u0435 Diamond<\/figcaption><\/figure>\n<h2>\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430  <\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435\u0439 \u043d\u0435\u043e\u0433\u0440\u0430\u0433\u0438\u0447\u0435\u043d\u043d\u043e, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0427\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0435 \u043d\u0435 \u043f\u0435\u0440\u043f\u0443\u0442\u0430\u043b\u0438\u0441\u044c \u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0445\u0430\u043e\u0442\u0438\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0442\u043e\u0440\u0430\u0434\u0436 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430, \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0435\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0432\u0435 \u0433\u0440\u0430\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u042d\u0442\u0438 \u0433\u0440\u0430\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0437 \u0441\u0435\u0431\u044f \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 ERC-721.<\/p>\n<pre><code>\/\/ SPDX-License-Identifier: MIT pragma solidity ^0.8.0;  \/\/ \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 library LibERC721 { \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430     bytes32 constant ERC721_POSITION = keccak256(\"erc721.storage\");   \/\/ \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f      struct ERC721Storage {         \/\/ tokenId => owner         mapping (uint256 => address) tokenIdToOwner;         \/\/ owner => count of tokens owned         mapping (address => uint256) ownerToNFTokenCount;         string name;         string symbol;        }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0438\u0437 \u0441\u043b\u043e\u0442\u0430 ERC721_POSITION     function getStorage() internal pure returns (ERC721Storage storage storageStruct) {         bytes32 position = ERC721_POSITION;         assembly {             storageStruct.slot := position         }     }     event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);  \/\/ \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0441\u0442\u044c \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c internal     function transferFrom(address _from, address _to, uint256 _tokenId) internal { \/\/ \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a getStorage, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e storage, \u044d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043e \u0442\u043e\u043c, \/\/ \u0447\u0442\u043e \u043c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u0438 \u0432\u043d\u043e\u0441\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \/\/ \u0430 \u043d\u0435 \u0432 memory \u0438\u043b\u0438 calldata         ERC721Storage storage erc721Storage = LibERC721.getStorage(); \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e         address tokenOwner = erc721Storage.tokenIdToOwner[_tokenId];         require(tokenOwner == _from);         erc721Storage.tokenIdToOwner[_tokenId] = _to;         erc721Storage.ownerToNFTokenCount[_from]--;         erc721Storage.ownerToNFTokenCount[_to]++;         emit Transfer(_from, _to, _tokenId);     } } \/\/ \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u043e \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435  \/\/ \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442  \/\/ \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 diamond, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f ERC721_POSITION \u043a\u0430\u043a \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0443, \/\/ \u0430 struct ERC721Storage \u043a\u0430\u043a \u0442\u0435\u043c\u043f\u043b\u0435\u0439\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \/\/ \u043a \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond contract ERC721Facet {     function name() external view returns (string memory name_) {         name_ = LibERC721.getStorage().name;     }          function symbol() external view returns (string memory symbol_) {         symbol_ = LibERC721.getStorage().symbol;     }      function transferFrom(address _from, address _to, uint256 _tokenId) external {         LibERC721.transferFrom(_from, _to, _tokenId);     } } \/\/ \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 contract ERC721BatchTransferFacet {     function batchTransferFrom(address _from, address _to, uint256[] calldata _tokenIds) external {         for(uint256 i; i &lt; _tokenIds.length; i++) {           LibERC721.transferFrom(_from, _to, _tokenIds[i]);         }     } }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u043e\u0440\u0430\u0434\u0436:<\/p>\n<ol>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0438\u0445 \u0432 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c mapping, \u043f\u043e\u043c\u0435\u0449\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043c\u0435\u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b, \u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u0435, \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0433\u0440\u0430\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u0438\u0445 \u0438 \u0442\u0435\u0445 \u0436\u0435 \u043c\u0435\u0441\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0433\u0440\u0430\u043d\u0435\u0439 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0433\u0434\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e, \u043a\u0430\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043d\u0435\u0439\u043c\u0438\u043d\u0433\u0430, \u0442\u0430\u043a \u0438 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430:<\/p>\n<ol>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0438\u043b\u0438 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0451, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u0432\u0430\u0441 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0430 \u0435\u0441\u0442\u044c mapping, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0442\u0430\u043a\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430, \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f Diamond. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0443\u044e \u043c\u0430\u043f\u0438\u043d\u0433\u043e\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0442\u043e \u0432\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u043f\u0438\u043d\u0433 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 Diamond \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043d\u043e\u043c\u0435\u0440 \u0441\u043b\u043e\u0442\u0430(ERC721_POSITION \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435) \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449. \u042d\u0442\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u0414\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438 \u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0441\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0439\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u043a\u0430\u044f-\u043b\u0438\u0431\u043e \u0433\u0440\u0430\u043d\u044c \u043c\u043e\u0433\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>selfdestruct<\/code>. \u041f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 <code>selfdestruct<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0433\u0440\u0430\u043d\u0438 \u0438 \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0439\u0442\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 delegatecall. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>selfdestruct<\/code> \u043c\u043e\u0436\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u043c\u0430\u0437\u043e\u043c, \u0438\u043b\u0438 <code>selfdestruct<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043a\u0441\u0438-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 Diamond.<\/p>\n<\/li>\n<\/ol>\n<p>\u0413\u0440\u0430\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0441\u0442\u043e\u0440\u0430\u0434\u0436\u0438. \u0413\u0440\u0430\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0433\u0440\u0430\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430.  <\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0430\u043d\u0435\u0439<\/figcaption><\/figure>\n<p>\u041d\u0430<\/p>\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-343696","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343696","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=343696"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343696\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}