{"id":370644,"date":"2024-05-21T04:30:01","date_gmt":"2024-05-21T04:30:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=370644"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=370644","title":{"rendered":"<span>Web3 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Twitter \u043d\u0430 React.js + Solidity | \u0447\u0430\u0441\u0442\u044c 2<\/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<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/822\/f67\/872\/822f678720311a077bbf67c836de151f.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/822\/f67\/872\/822f678720311a077bbf67c836de151f.png\"\/><\/figure>\n<p>Hello, \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799407\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0431\u044b\u043b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d backend \u043d\u0430 Solidity, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0438\u0441\u0430\u0442\u044c frontend \u043d\u0430 React.<\/p>\n<blockquote>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0434\u0430\u043b\u0451\u043a \u043e\u0442 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u043c \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/blockquote>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <strong>web3,<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0435.<\/p>\n<p><code>$ npx create-react-app client<\/code> <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/982\/775\/56e\/98277556e02bb16010dd8f1169789df8.png\" width=\"1063\" height=\"227\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/982\/775\/56e\/98277556e02bb16010dd8f1169789df8.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438: <code>react-router-dom<\/code>\u0438<code>web3<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c.<\/p>\n<pre><code class=\"bash\">cd client npm i react-router-dom, web3<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 <code>yarn<\/code>:<\/p>\n<pre><code class=\"assembly\">cd client yarn add web3 yarn add react-router-dom<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f91\/7f6\/df7\/f917f6df795553cfa46f74d45b3daefd.png\" width=\"1020\" height=\"609\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f91\/7f6\/df7\/f917f6df795553cfa46f74d45b3daefd.png\"\/><\/figure>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <strong>\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong> \u043b\u0438\u0448\u043d\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/355\/92e\/889\/35592e88992200b5cce4b87a1161e900.png\" alt=\"\u0423\u0434\u0430\u043b\u044f\u0435\u043c\" title=\"\u0423\u0434\u0430\u043b\u044f\u0435\u043c\" width=\"461\" height=\"314\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/355\/92e\/889\/35592e88992200b5cce4b87a1161e900.png\"\/><\/p>\n<div><figcaption>\u0423\u0434\u0430\u043b\u044f\u0435\u043c<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0444\u0430\u0439\u043b <strong>index.js <\/strong>\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>BrowserRouter<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>react-router-dom<\/code> , \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>App<\/code> \u0432 \u0440\u043e\u0443\u0442\u0435\u0440. \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0447\u0438\u0441\u0442\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/678\/786\/5dc\/6787865dc177cfee86068a4a0548e1a6.png\" width=\"1205\" height=\"567\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/678\/786\/5dc\/6787865dc177cfee86068a4a0548e1a6.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0435 \u043f\u0430\u043f\u043a\u0438: <strong>config<\/strong> \u0438 <strong>contexts. <\/strong>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>config <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430: <strong>abi.json <\/strong>(\u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 abi \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430)<strong> <\/strong>\u0438 <strong>contract.js <\/strong>(\u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430).<br \/>P.S: \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 1 \u0431\u043b\u043e\u043a\u0435 \u0432 <code>Ganache<\/code> .<\/p>\n<blockquote>\n<p>ABI &#8212; \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 &#8212; \u044d\u0442\u043e \u043a\u0430\u043a \u0431\u044b \u044f\u0437\u044b\u043a \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438, ABI \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043a\u0430\u043a \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438. \u042d\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/blockquote>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>contexts <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <strong>ContractContext.js <\/strong>\u0432 \u043d\u0435\u043c \u043c\u044b \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0443 <code>MetaMask<\/code> \u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u043a \u043d\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u0430\u0439\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0432 <code>useContract<\/code>.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fad\/ee1\/7b2\/fadee17b2396ae6265bf6baccc0f7ab7.png\" width=\"278\" height=\"302\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fad\/ee1\/7b2\/fadee17b2396ae6265bf6baccc0f7ab7.png\"\/><\/figure>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <strong>contract.js<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u0447\u043a\u0430:<\/p>\n<pre><code class=\"javascript\">export const contract_address = \"\u0430\u0434\u0440\u0435\u0441 \u0432\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\";<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <strong>ABI <\/strong>\u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b <strong>abi.json<\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 <strong>contracts <\/strong>\u0441 \u043d\u0430\u0448\u0438\u043c \u0431\u044d\u043a\u044d\u043d\u0434\u043e\u043c \u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 <strong>build\/contarcts<\/strong> \u0438 \u0432 \u043d\u0435\u0439 \u0444\u0430\u0439\u043b <strong>Twitter.json. <\/strong>\u0412 \u043d\u0435\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u043c <strong>abi <\/strong>\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a03\/521\/5e6\/a035215e688d485aa658133c434a2c62.png\" width=\"816\" height=\"351\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a03\/521\/5e6\/a035215e688d485aa658133c434a2c62.png\"\/><\/figure>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432 \u043d\u0430\u0448 \u0444\u0430\u0439\u043b <strong>abi.json. <\/strong>\u041d\u0438\u0436\u0435 <strong>abi <\/strong>\u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/articles\/799407\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">[     {       \"inputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"constructor\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_username\",           \"type\": \"string\"         },         {           \"internalType\": \"string\",           \"name\": \"_password\",           \"type\": \"string\"         }       ],       \"name\": \"Registration\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_password\",           \"type\": \"string\"         }       ],       \"name\": \"Login\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [],       \"name\": \"Logout\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_text\",           \"type\": \"string\"         }       ],       \"name\": \"AddTwitt\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"UserTwitts\",       \"outputs\": [         {           \"components\": [             {               \"components\": [                 {                   \"internalType\": \"address\",                   \"name\": \"login\",                   \"type\": \"address\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"password\",                   \"type\": \"string\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"username\",                   \"type\": \"string\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"avatar\",                   \"type\": \"string\"                 }               ],               \"internalType\": \"struct Twitter.User\",               \"name\": \"author\",               \"type\": \"tuple\"             },             {               \"internalType\": \"string\",               \"name\": \"text\",               \"type\": \"string\"             },             {               \"internalType\": \"uint256\",               \"name\": \"likes\",               \"type\": \"uint256\"             },             {               \"internalType\": \"uint256\",               \"name\": \"createdTime\",               \"type\": \"uint256\"             }           ],           \"internalType\": \"struct Twitter.Twitt[]\",           \"name\": \"\",           \"type\": \"tuple[]\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"CheckRegistration\",       \"outputs\": [         {           \"internalType\": \"bool\",           \"name\": \"\",           \"type\": \"bool\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"GetUser\",       \"outputs\": [         {           \"components\": [             {               \"internalType\": \"address\",               \"name\": \"login\",               \"type\": \"address\"             },             {               \"internalType\": \"string\",               \"name\": \"password\",               \"type\": \"string\"             },             {               \"internalType\": \"string\",               \"name\": \"username\",               \"type\": \"string\"             },             {               \"internalType\": \"string\",               \"name\": \"avatar\",               \"type\": \"string\"             }           ],           \"internalType\": \"struct Twitter.User\",           \"name\": \"\",           \"type\": \"tuple\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_avatar\",           \"type\": \"string\"         }       ],       \"name\": \"UpdateUser\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     }   ]<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0438\u0448\u0435\u043c <code>ContractProvider<\/code> , \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u044b \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 js \u0438 react, \u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u043c.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c web3 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u043d\u0430\u0448 \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <strong>abi. <\/strong><\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 <code>ContractContext<\/code>.<\/p>\n<blockquote>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043d\u0438\u0437 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u043f\u0441\u043e\u0432.  <\/p>\n<\/blockquote>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/397\/c3c\/a91\/397c3ca911a475d9a5bbab6e5cf6dd1c.png\" width=\"888\" height=\"269\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/397\/c3c\/a91\/397c3ca911a475d9a5bbab6e5cf6dd1c.png\"\/><\/figure>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 <code>ContractProvider<\/code> \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439.<\/p>\n<ol>\n<li>\n<p><code>contract <\/code>&#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>account<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<\/li>\n<li>\n<p><code>accounts<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><code>balance<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0431\u0430\u043b\u0430\u043d\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"javascript\">const [contract, setContract] = useState(null); const [account, setAccount] = useState(null); const [accounts, setAccounts] = useState([]); const [balance, setBalance] = useState();<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0412 \u043d\u0435\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>web3<\/code> \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Ethereum. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u0434\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>MetaMask<\/code> \u0438\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0438 \u043f\u043e\u0440\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0432 <code>Ganache<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>MetaMask<\/code> \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e, \u0442\u043e \u0447\u0435\u0440\u0435\u0437 <code>window.ethereum.request<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b \u0438 \u043f\u0435\u0440\u0432\u044b\u0439 ([0]) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>web3.eth.getBalance(accounts[0])<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u0430\u043b\u0430\u043d\u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u0430 (\u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0438\u0437 <strong>wei<\/strong> \u0432 <strong>ether<\/strong>) \u0438 \u0431\u0435\u0440\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0435 7 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<pre><code class=\"javascript\">const contractInstance = new web3.eth.Contract(abi, contract_address); setContract(contractInstance);<\/code><\/pre>\n<p>\u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0432 <strong>try-catch <\/strong>\u0434\u043b\u044f \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u043d\u0443\u0442\u0440\u0438 <code>UseEffect<\/code>, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">useEffect(() => {     const initializeContract = async () => {       const web3 = new Web3(Web3.givenProvider || 'http:\/\/127.0.0.1:7545');       if (window.ethereum) {         try {           const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });           if (accounts &amp;&amp; accounts.length > 0) {             setAccounts(accounts);             setAccount(accounts[0]);                const weiBalance = await web3.eth.getBalance(accounts[0]);             const etherBalance = web3.utils.fromWei(weiBalance, 'ether');             setBalance(etherBalance.slice(0, 8));              const contractInstance = new web3.eth.Contract(abi, contract_address);             setContract(contractInstance);           } else {             console.error('No accounts found');           }         } catch (error) {           console.error('Error fetching account balance:', error);         }       } else {         alert('Install MetaMask extension!');       }     };      initializeContract();   }, []);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b\u0435 \u0432 <code>ContractContext.Provider<\/code> \u0438 \u043d\u0430\u0448\u0438 \u0441\u0442\u0435\u0439\u0442\u044b \u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430\u043c\u0438, \u0431\u0430\u043b\u0430\u043d\u0441\u043e\u043c \u0438 \u0442.\u0434.<\/p>\n<pre><code class=\"javascript\">return (     &lt;ContractContext.Provider value={{ contract, account, balance, accounts }}>       {children}     &lt;\/ContractContext.Provider> );<\/code><\/pre>\n<h2>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/h2>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ ContractContext.js import React, { createContext, useContext, useState, useEffect } from 'react'; import Web3 from 'web3'; import { contract_address } from '..\/config\/contract'; import abi from '..\/config\/abi.json';  const ContractContext = createContext();  export const ContractProvider = ({ children }) => {   const [contract, setContract] = useState(null);   const [account, setAccount] = useState(null);   const [accounts, setAccounts] = useState([]);   const [balance, setBalance] = useState();    useEffect(() => {     const initializeContract = async () => {       const web3 = new Web3(Web3.givenProvider || 'http:\/\/127.0.0.1:7545');       if (window.ethereum) {         try {           const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });           if (accounts &amp;&amp; accounts.length > 0) {             setAccounts(accounts);             setAccount(accounts[0]);                const weiBalance = await web3.eth.getBalance(accounts[0]);             const etherBalance = web3.utils.fromWei(weiBalance, 'ether');             setBalance(etherBalance.slice(0, 8));              const contractInstance = new web3.eth.Contract(abi, contract_address);             setContract(contractInstance);           } else {             console.error('No accounts found');           }         } catch (error) {           console.error('Error fetching account balance:', error);         }       } else {         alert('Install MetaMask extension!');       }     };      initializeContract();   }, []);    return (     &lt;ContractContext.Provider value={{ contract, account, balance, accounts }}>       {children}     &lt;\/ContractContext.Provider>   ); };  export const useContract = () => {   const context = useContext(ContractContext);   if (!context) {     throw new Error('useContract must be used within a ContractProvider');   }   return context; };<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c <code>router<\/code> \u0438 <code>app<\/code> \u0432 \u043d\u0430\u0448 <code>ContractProvider<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e98\/2fc\/618\/e982fc618b7a1c77979b16e4508b2625.png\" width=\"972\" height=\"402\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e98\/2fc\/618\/e982fc618b7a1c77979b16e4508b2625.png\"\/><\/figure>\n<h2>\u0412\u0435\u0440\u0441\u0442\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/h2>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0442\u043a\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0434 \u0432\u0441\u0435\u0445 <strong>css<\/strong> \u0444\u0430\u0439\u043b\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435, \u043d\u0435 \u0432\u0438\u0436\u0443 \u0441\u043c\u044b\u0441\u043b\u0430 \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0437\u0430\u0439\u043d\u0435.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0432\u043e\u0439 <code>header<\/code>, \u0442.\u043a. \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d, \u0434\u0430\u0432\u0438\u043c \u043d\u0430 \u043d\u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u043a\u043e\u043d\u043a\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 <strong>components <\/strong>\u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u0430\u043f\u043a\u0443 \u0441 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438, \u0432 \u043d\u0435\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6c4\/79a\/dc4\/6c479adc4141c8461299df7fb37127ec.png\" width=\"844\" height=\"457\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6c4\/79a\/dc4\/6c479adc4141c8461299df7fb37127ec.png\"\/><\/figure>\n<p>\u0412 <code>CustomHeader<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0434\u043b\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>Link<\/code> \u0438\u0437 <code>react-router-dom<\/code>.<\/p>\n<pre><code class=\"javascript\">export default function CustomHeader() {   return (     &lt;div style={{         height: '10vh',          backgroundColor: theme.primaryColor,         display: 'flex',          alignItems: 'center',         justifyContent: 'space-between',         paddingInline: '10%'       }}       >        &lt;Link to={\"\/\"}>&lt;h1 style={{color: 'white'}}>Twitter dApp&lt;\/h1>&lt;\/Link>       &lt;Link to={\"\/profile\"}>         &lt;img style={{           width: '6vh',            height: '6vh'}}            src={process.env.PUBLIC_URL + '\/userIcon.png'}            alt='user'\/>       &lt;\/Link>     &lt;\/div>   ) }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043a\u0443 <strong>pages <\/strong>\u0438 \u0432 \u043d\u0435\u0439 4 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b: \u0433\u043b\u0430\u0432\u043d\u0430\u044f, \u043f\u0440\u043e\u0444\u0438\u043b\u044c, \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 &#171;404&#187;. \u0421\u0435\u0439\u0447\u0430\u0441 \u0432 \u043d\u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e <code>div<\/code> \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1fe\/3cd\/327\/1fe3cd327701a85acd9f804c543b71d1.png\" width=\"259\" height=\"140\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1fe\/3cd\/327\/1fe3cd327701a85acd9f804c543b71d1.png\"\/><\/figure>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0444\u0430\u0439\u043b <strong>App.js <\/strong>\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 <code>CustomHeader<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 <code>CustomHeader<\/code> \u0438 <code>routes<\/code>. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 <strong>pages<\/strong>.<\/p>\n<blockquote>\n<p>\u0423 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b &#171;404&#187; \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0443\u0442\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c &#171;*&#187;. \u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0443\u0442\u044c \u043d\u0430 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 (\u043b\u044e\u0431\u043e\u0439 \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u0445, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438), \u0435\u043c\u0443 \u0432\u044b\u0434\u0430\u0441\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<p>\u0423 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043f\u0443\u0442\u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#171;:userAdr&#187; \u0447\u0442\u043e\u0431\u044b \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.<\/p>\n<\/blockquote>\n<pre><code class=\"javascript\">function App() {   return (     &lt;div className=\"App\">       &lt;CustomHeader\/>        &lt;Routes>         &lt;Route path=\"\/\" element={&lt;Home\/>} \/>         &lt;Route path=\"\/profile\" element={&lt;Profile\/>} \/>         &lt;Route path='\/user\/:userAdr' element={&lt;User\/>} \/>         &lt;Route path='*' element={&lt;ErrorPage\/>} \/>       &lt;\/Routes>     &lt;\/div>   ); }<\/code><\/pre>\n<p>\u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043d\u0430\u0434\u043f\u0438\u0441\u044c \u0438 \u043a\u043d\u043e\u043f\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0443\u044e \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 (&#171;\/&#187;).<\/p>\n<pre><code class=\"javascript\">return (     &lt;div className='App-header'>       &lt;h1 style={{textAlign: 'center'}}>Oops...&lt;br\/>Page not found&lt;\/h1>       &lt;Link to=\"\/\" style={{         backgroundColor: '#3366FF',          padding: '10px',         paddingInline: '20px',          borderRadius: '5px',         color: 'white'}}>Go home&lt;\/Link>     &lt;\/div> )<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>Ganache<\/code> \u0438 \u043a\u043b\u0438\u0435\u043d\u0442:<\/p>\n<pre><code>cd client npm run start<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448 header \u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u043e\u043a\u043d\u043e <code>MetaMask<\/code> \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1c2\/aa0\/f62\/1c2aa0f62a4b7594e5feed79078f7332.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1c2\/aa0\/f62\/1c2aa0f62a4b7594e5feed79078f7332.png\"\/><\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u043f\u0443\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439. \u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>\u0442\u0432\u0438\u0442\u0442\u0430<\/strong> \u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0444\u0438\u043b\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f75\/644\/f04\/f75644f0412ac56d889f1ef1cb09a9fa.png\" width=\"1920\" height=\"1020\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f75\/644\/f04\/f75644f0412ac56d889f1ef1cb09a9fa.png\"\/><\/figure>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>components <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <strong>Twitt.jsx, <\/strong>\u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0430\u043c \u0442\u0432\u0438\u0442\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0432\u0438\u0442\u0442\u043e\u0432.<\/p>\n<p> \u0418\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0434\u0440\u0435\u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430, \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0430. \u041e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 <code>isOwner<\/code>, \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u043e\u043c \u0442\u0432\u0438\u0442\u0442\u0430. \u0422\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0434\u0430\u0442\u0443 \u0432 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442.<\/p>\n<pre><code class=\"javascript\">const { account } = useContract(); const isOwner = account == twit.author.login.toLowerCase();  const date = new Date(Number(twit.createdTime) * 1000); const formattedDateTime = date.toLocaleString();<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0432 <code>div<\/code> \u0431\u043b\u043e\u043a\u0438 \u043f\u043e\u043b\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u0430 \u0438 \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0443 \u0430\u0432\u0442\u043e\u0440\u0430 \u0438 \u043d\u0438\u043a\u043d\u0435\u0439\u043c \u0432 <code>Link<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. <\/p>\n<blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u043e\u043c \u0442\u0432\u0438\u0442\u0442\u0430, \u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0430\u0432\u0442\u043e\u0440\u0430, \u0430 \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u044c. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0430\u0432\u0442\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 <code>twitt<\/code>.<\/p>\n<p><strong>P.S<\/strong>: \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0438 \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u0434\u0438\u0437\u0430\u0439\u043d \u0434\u043b\u044f \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0438 \u0433\u043e\u0441\u0442\u044f. \u041d\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430 \u0434\u0432\u0435.<\/p>\n<\/blockquote>\n<pre><code class=\"javascript\">import React from 'react' import theme from '..\/constants\/colors' import '.\/Twitt.css'; import { Link } from 'react-router-dom'; import { useContract } from '..\/contexts\/ContractContext';  export default function Twitt({twit}) {     const { account } = useContract();     const isOwner = account == twit.author.login.toLowerCase();          const date = new Date(Number(twit.createdTime) * 1000);     const formattedDateTime = date.toLocaleString();      return (         &lt;div className='Twitt'>             &lt;Link style={{color: 'black'}} to={isOwner ? '\/profile' : `\/user\/${twit.author.login}`}>                 &lt;div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '2vh'}}>                     &lt;img className='twitt-pic' src={twit.author.avatar ? twit.author.avatar : `${process.env.PUBLIC_URL}\/profile-pic.png`} alt=\"Profile Picture\"\/>                     &lt;div>                         &lt;h3>@{twit.author.username}&lt;\/h3>                         &lt;h3 style={{color: theme.primaryColor}}>{formattedDateTime}&lt;\/h3>                     &lt;\/div>                 &lt;\/div>             &lt;\/Link>             &lt;h3 style={{marginTop: '2vh'}}>{twit.text}&lt;\/h3>             &lt;div className=\"likes\">                 &lt;img src={process.env.PUBLIC_URL+'\/like.png'} className='like'\/>                 &lt;h3>{twit.likes.toString()}&lt;\/h3>             &lt;\/div>         &lt;\/div>     ) }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u044f, \u0432 \u043d\u0435\u0439 \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0435\u0439\u0442\u043e\u0432. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u044b \u0432\u0445\u043e\u0434\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438\u043b\u0438 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043a\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0431\u0430\u043b\u0430\u043d\u0441 \u0438 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0430\u043c \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0432\u0445\u043e\u0434\u0430 \u0438 \u0442\u0435\u043a\u0441\u0442\u0430 \u0442\u0432\u0438\u0442\u0442\u0430 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e boolean \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. <code>isOpened<\/code> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (\u043f\u0440\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 <code>true<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443).<\/p>\n<pre><code class=\"javascript\">const { contract, balance, account } = useContract(); const [user, setUser] = useState(); const [link, setLink] = useState();  const [text, setText] = useState(''); const [username, setUsername] = useState(''); const [password, setPassword] = useState('');  const [isOpened, setIsOpened] = useState(false); const [isLogged, setIsLogged] = useState(false); const [isRegistered, setIsRegistered] = useState(false);  const [twitts, setTwitts] = useState([]);<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c <code>useEffect<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u0442\u0440\u0435\u0445 \u0441\u0442\u0435\u0439\u0442\u043e\u0432 (\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0438\u043b\u0438 \u0432\u0445\u043e\u0434). \u0415\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437 <code>localStorage<\/code>, \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0443\u044e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043b\u0438 \u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0442\u0432\u0438\u0442\u0442\u044b. \u0421\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0438\u0436\u0435.<\/p>\n<pre><code class=\"javascript\">useEffect(() => {   if (contract) {     const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';     setIsLogged(isLoggedIn);      CheckRegistration();          if(isLogged) {       GetUserData();       getUserTwitts();     }   } }, [isLogged, contract, isRegistered]);<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c, \u0432 \u043d\u0435\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>estimateGas<\/code> \u0443\u0437\u043d\u0430\u0435\u043c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0435\u0435 \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c. \u0412 <code>Ganache<\/code> \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c 0-\u0443\u044e \u0446\u0435\u043d\u0443 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0433\u0430\u0437 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0412\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <code>from: account<\/code>.<\/p>\n<pre><code class=\"javascript\">const sendTransaction = async (method, args) => {   try {     const gasEstimation = await method(...args).estimateGas({ from: account });     await method(...args).send({ from: account, gas: gasEstimation });   } catch (err) {     alert(err);   } };<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0432\u0438\u0442\u0442\u0430 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u043f\u0443\u0441\u0442\u044b\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u0445 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>sendTransaction<\/code>, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <code>method<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">const AddTwitt = async(_text) => {   if(!_text) return;    try {     await sendTransaction(contract.methods.AddTwitt, [_text]);      setText('');     getUserTwitts();   } catch (err) {     alert(err);   } }  const Registration = async(_username, _password) => {   if(!_username || !_password) return;   try {     await sendTransaction(contract.methods.Registration, [_username, _password]);      setIsRegistered(true);   } catch (err) {     alert(err);   } }  const Login = async(_password) => {   if(!_password) return;   try {     await sendTransaction(contract.methods.Login, [_password]);      localStorage.setItem('isLoggedIn', true);     setIsLogged(true);   } catch (err) {     alert(err);   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 <code>call<\/code>, \u0438 \u043d\u0435 \u043f\u043b\u0430\u0442\u0438\u043c \u0437\u0430 \u0438\u0445 \u0432\u044b\u0437\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0433\u0430\u0437\u0430. \u0412 \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 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442.\u043a. \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<pre><code class=\"javascript\">const getUserTwitts = async() => {   try {     const twitts = await contract.methods.UserTwitts(account).call({ from: account });      setTwitts(twitts);   } catch (err) {     alert(err);   } }  const GetUserData = async() => {   try {     const user = await contract.methods.GetUser(account).call({ from: account });      setUser(user);   } catch (err) {     alert(err);   } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0442\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0412\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0432\u043e\u0448\u0435\u043b \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0438 \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0435\u043c\u0443 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0438 \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0430\u043a\u043a\u0430\u0443\u043d\u0442, \u0443 \u043d\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u043f\u0430\u0440\u043e\u043b\u044f (\u0432\u0435\u0434\u044c \u043b\u043e\u0433\u0438\u043d\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u0440\u0435\u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430).<br \/>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0435, \u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u0432\u044b\u0445\u043e\u0434\u0430.<\/p>\n<pre><code class=\"javascript\">&lt;div>   {     isLogged        ? (&lt;button className='edit-btn' onClick={() => Exit()}>exit&lt;\/button>)       : (           isRegistered           ? (             &lt;div className='registration'>               &lt;input type='text' placeholder='password' value={password} onChange={e => setPassword(e.target.value)}\/>               &lt;button className='edit-btn' style={{margin: '0'}} onClick={() => Login(password)}>login&lt;\/button>             &lt;\/div>             )           : (             &lt;div className='registration'>               &lt;input type='text' placeholder='username' value={username} onChange={e => setUsername(e.target.value)}\/>               &lt;input type='text' placeholder='password' value={password} onChange={e => setPassword(e.target.value)}\/>               &lt;button className='edit-btn' style={{margin: '0'}} onClick={() => Registration(username, password)}>registration&lt;\/button>             &lt;\/div>             )         )   } &lt;\/div><\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u043c \u043c\u0435\u043d\u044e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0438, \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0441\u0441\u044b\u043b\u043a\u0438 \u0438 \u043d\u043e\u0432\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430.<\/p>\n<pre><code class=\"javascript\">&lt;div className='sidebar'>   {user &amp;&amp; &lt;h2 style={{marginBottom: '4vh'}}>     &lt;span style={{color: 'gray'}}>Username:&lt;\/span>&lt;br\/>@{user.username}   &lt;\/h2>}   {isOpened &amp;&amp; &lt;input type='text' style={{marginBottom: '1vh'}} placeholder='link to img' value={link} onChange={e => setLink(e.target.value)}\/>}   {isOpened      ? &lt;button className='edit-btn' onClick={() => UpdateAvatar(link)}>save&lt;\/button>     : &lt;button className='edit-btn' onClick={() => setIsOpened(true)}>update avatar&lt;\/button>   } &lt;\/div><\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0432\u0441\u0435\u0445 \u0442\u0432\u0438\u0442\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 <code>map<\/code> \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0442\u0432\u0438\u0442\u0442\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0432\u0438\u0442\u0442 \u0432 \u043d\u0430\u0448 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Twitt<\/code>, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0432\u0438\u0442\u0442\u0430, \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0438\u0445 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0438\u0441\u044c \u043d\u043e\u0432\u044b\u0435.<\/p>\n<blockquote>\n<p>\u041b\u0443\u0447\u0448\u0435 <\/p>\n<\/blockquote>\n<pre><code class=\"javascript\">{   twitts.sort((a, b) => Number(b.createdTime) - Number(a.createdTime)).map((twit) => {     return (       &lt;Twitt key={twit.createdTime} twit={twit} \/>     );   }) }<\/code><\/pre>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u043e\u0444\u0438\u043b\u044f<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import React from 'react' import '..\/App.css'; import { useEffect, useState } from 'react'; import '.\/Profile.css'; import theme from '..\/constants\/colors'; import { useContract } from '..\/contexts\/ContractContext'; import Twitt from '..\/components\/Twitt';  export default function Profile() {     const { contract, balance, account } = useContract();     const [user, setUser] = useState();     const [link, setLink] = useState();      const [text, setText] = useState('');     const [username, setUsername] = useState('');     const [password, setPassword] = useState('');      const [isOpened, setIsOpened] = useState(false);     const [isLogged, setIsLogged] = useState(false);     const [isRegistered, setIsRegistered] = useState(false);          const [twitts, setTwitts] = useState([]);      useEffect(() => {       if (contract) {         const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';         setIsLogged(isLoggedIn);          CheckRegistration();                  if(isLogged) {           GetUserData();           getUserTwitts();         }       }     }, [isLogged, contract, isRegistered]);      const sendTransaction = async (method, args) => {       try {         const gasEstimation = await method(...args).estimateGas({ from: account });         await method(...args).send({ from: account, gas: gasEstimation });       } catch (err) {         alert(err);       }     };      const AddTwitt = async(_text) => {       if(!_text) return;        try {         await sendTransaction(contract.methods.AddTwitt, [_text]);          setText('');         getUserTwitts();       } catch (err) {         alert(err);       }     }      const Registration = async(_username, _password) => {       if(!_username || !_password) return;       try {         await sendTransaction(contract.methods.Registration, [_username, _password]);          setIsRegistered(true);       } catch (err) {         alert(err);       }     }      const Login = async(_password) => {       if(!_password) return;       try {         await sendTransaction(contract.methods.Login, [_password]);          localStorage.setItem('isLoggedIn', true);         setIsLogged(true);       } catch (err) {         alert(err);       }     }      const getUserTwitts = async() => {       try {         const twitts = await contract.methods.UserTwitts(account).call({ from: account });          setTwitts(twitts);       } catch (err) {         alert(err);       }     }      const GetUserData = async() => {       try {         const user = await contract.methods.GetUser(account).call({ from: account });          setUser(user);       } catch (err) {         alert(err);       }     }      const UpdateAvatar = async(link) => {       if(!link) return;       try {         await sendTransaction(contract.methods.UpdateUser, [link]);          setLink('');         setIsOpened(false);         GetUserData();       } catch (err) {         alert(err);       }     }      const Exit = async() => {       try {         await sendTransaction(contract.methods.Logout, []);          localStorage.setItem('isLoggedIn', false);         setIsLogged(false);         setTwitts([]);       } catch (err) {         alert(err);       }     }      const CheckRegistration = async() => {       try {         const result = await contract.methods.CheckRegistration(account).call({ from: account });         setIsRegistered(result);       } catch (err) {         alert(err);       }     }      return (       &lt;div className='main'>         &lt;div className='container'            style={{             alignItems: 'start',              justifyContent: 'flex-start',             gap: '5vh'}}>           &lt;div>             &lt;img src={user &amp;&amp; user.avatar ? user.avatar : process.env.PUBLIC_URL + '\/basicProfile.png'} alt=\"avatar\" className='avatar' \/>           &lt;\/div>           &lt;div className='user-info'>             &lt;div style={{marginTop: '5vh'}}>               &lt;h2>Account: &lt;span style={{color: theme.primaryColor}}>{account}&lt;\/span>&lt;\/h2>               &lt;h2>Balance: {balance} BEBRA&lt;\/h2>             &lt;\/div>             {               isLogged                  ? (&lt;button className='edit-btn' onClick={() => Exit()}>exit&lt;\/button>)                 : (                     isRegistered                     ? (                       &lt;div className='registration'>                         &lt;input type='text' placeholder='password' value={password} onChange={e => setPassword(e.target.value)}\/>                         &lt;button className='edit-btn' style={{margin: '0'}} onClick={() => Login(password)}>login&lt;\/button>                       &lt;\/div>                       )                     : (                       &lt;div className='registration'>                         &lt;input type='text' placeholder='username' value={username} onChange={e => setUsername(e.target.value)}\/>                         &lt;input type='text' placeholder='password' value={password} onChange={e => setPassword(e.target.value)}\/>                         &lt;button className='edit-btn' style={{margin: '0'}} onClick={() => Registration(username, password)}>registration&lt;\/button>                       &lt;\/div>                       )                   )             }           &lt;\/div>         &lt;\/div>                  &lt;div className=\"container\" style={{             alignItems: 'start',              justifyContent: 'flex-start',              marginBottom: '5vh',             gap: '5vh'             }}>                      {isLogged &amp;&amp; &lt;div className='sidebar'>             {user &amp;&amp; &lt;h2 style={{marginBottom: '4vh'}}>               &lt;span style={{color: 'gray'}}>Username:&lt;\/span>&lt;br\/>@{user.username}             &lt;\/h2>}             {isOpened &amp;&amp; &lt;input type='text' style={{marginBottom: '1vh'}} placeholder='link to img' value={link} onChange={e => setLink(e.target.value)}\/>}             {isOpened                ? &lt;button className='edit-btn' onClick={() => UpdateAvatar(link)}>save&lt;\/button>               : &lt;button className='edit-btn' onClick={() => setIsOpened(true)}>update avatar&lt;\/button>             }           &lt;\/div>}           &lt;div style={{display: 'flex', flexDirection: 'column', gap: '5vh', width: '80%'}}>             {isLogged &amp;&amp; &lt;div className='add-twitt'>               &lt;textarea className='input_twitt' type='text' placeholder='What are you thinking?' value={text} onChange={e => setText(e.target.value)}\/>               &lt;button onClick={() => AddTwitt(text)} disabled={!isLogged} className='add-btn'>Twitt it&lt;\/button>             &lt;\/div>}              {               twitts.sort((a, b) => Number(b.createdTime) - Number(a.createdTime)).map((twit) => {                 return (                   &lt;Twitt key={twit.createdTime} twit={twit} \/>                 );               })             }           &lt;\/div>         &lt;\/div>        &lt;\/div>     ) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0438 \u0432\u0438\u0434\u0438\u043c \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u043e\u0439\u0442\u0438 \u0432 \u043d\u0435\u0433\u043e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a68\/a99\/4f1\/a68a994f1e799c3ae92f0b55a5c5c95e.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a68\/a99\/4f1\/a68a994f1e799c3ae92f0b55a5c5c95e.png\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u0431\u043b\u043e\u043a\u0438, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u043e\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u0432\u0438\u0442\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/974\/441\/a1b\/974441a1b85c2f86209e04fc4eaca114.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/974\/441\/a1b\/974441a1b85c2f86209e04fc4eaca114.png\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0432\u0438\u0442\u0442\u0430 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u043c \u0435\u0433\u043e \u0432 \u043b\u0435\u043d\u0442\u0435, \u0442\u0430\u043a\u0436\u0435 \u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0443 \u043d\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 (\u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0433\u0438\u0444\u043a\u0443).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cbb\/f84\/76c\/cbbf8476c4aaaa92bc05fde1cfb0232a.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cbb\/f84\/76c\/cbbf8476c4aaaa92bc05fde1cfb0232a.png\"\/><\/figure>\n<h2>\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0435\u043b\u043e \u0437\u0430 \u043c\u0430\u043b\u044b\u043c, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0442\u0432\u0438\u0442\u0442\u0430\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0435\u0439\u0442 \u0434\u043b\u044f \u0442\u0432\u0438\u0442\u0442\u043e\u0432 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0432\u0441\u0435 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u043c \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0442\u0432\u0438\u0442\u0442\u043e\u0432. \u0412 \u043d\u0435\u0439 \u043c\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430\u043c \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0432\u0438\u0442\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0447\u0435\u0439 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0412\u0441\u0435 \u0442\u0432\u0438\u0442\u0442\u044b \u0437\u0430\u043d\u043e\u0441\u0438\u043c \u0432 \u0441\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0432\u0438\u0442\u0442\u044b \u0438 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0446\u0438\u043a\u043b\u0430 \u0437\u0430\u043d\u043e\u0441\u0438\u043c \u0442\u0432\u0438\u0442\u0442\u044b \u0432 \u0441\u0442\u0435\u0439\u0442.<\/p>\n<blockquote>\n<p>\u041d\u0435 \u043b\u0443\u0447\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u0441\u0442\u043e\u0438\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0440\u043d\u0435\u0442 \u0432\u0441\u0435 \u0442\u0432\u0438\u0442\u0442\u044b. \u041d\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435.<\/p>\n<\/blockquote>\n<pre><code class=\"javascript\">const getAllTwitts = async() => {   try {     const uniqueTwittsSet = new Set();      for (const acc of accounts) {       if(acc != account) {         const _twitts = await contract.methods.UserTwitts(acc).call({ from: account });                _twitts.forEach((twit) => uniqueTwittsSet.add(twit));       }     };      const uniqueTwittsArray = [...uniqueTwittsSet];      setTwitts(uniqueTwittsArray);   } catch (err) {     alert(err);   } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0442\u0430\u043a\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 <code>map<\/code>, \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0442\u0432\u0438\u0442\u0442\u044b.<\/p>\n<pre><code class=\"javascript\">import React, {useEffect, useState} from 'react' import { useContract } from '..\/contexts\/ContractContext'; import Twitt from '..\/components\/Twitt';  export default function Home() {   const { contract, accounts, account } = useContract();   const [twitts, setTwitts] = useState([]);    const getAllTwitts = async() => {     try {       const uniqueTwittsSet = new Set();        for (const acc of accounts) {         if(acc != account) {           const _twitts = await contract.methods.UserTwitts(acc).call({ from: account });                    _twitts.forEach((twit) => uniqueTwittsSet.add(twit));         }       };        const uniqueTwittsArray = [...uniqueTwittsSet];        setTwitts(uniqueTwittsArray);     } catch (err) {       alert(err);     }   }    useEffect(() => {     if (contract) {       getAllTwitts();     }   }, [contract]);    return (     &lt;div className='main'>       &lt;div className=\"container\" style={{display: 'flex', justifyContent: 'center', marginBottom: '5vh'}}>         &lt;div style={{display: 'flex', flexDirection: 'column', gap: '5vh', width: '80%'}}>           {             twitts.sort((a, b) => Number(b.createdTime) - Number(a.createdTime)).map((twit) => {               return (                 &lt;Twitt key={twit.createdTime}  twit={twit} \/>               );             })           }         &lt;\/div>       &lt;\/div>     &lt;\/div>   ) }<\/code><\/pre>\n<p>\u0412\u044b\u0439\u0434\u0435\u043c \u0438\u0437 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u0435 \u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0432 <code>MetaMask<\/code>, \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u043c \u044d\u0442\u0430\u043f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u0432\u0438\u0442\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5b2\/c5d\/287\/5b2c5d28772878c269265e8fb95f85f8.png\" alt=\"\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442\" title=\"\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442\" width=\"1543\" height=\"771\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5b2\/c5d\/287\/5b2c5d28772878c269265e8fb95f85f8.png\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3ce\/984\/66d\/3ce98466d20eda555c88a0d8bcd0597c.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ce\/984\/66d\/3ce98466d20eda555c88a0d8bcd0597c.png\"\/><\/figure>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0442\u0432\u0438\u0442\u0442 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442.\u043a. \u0437\u0430\u0448\u043b\u0438 \u0437\u0430 \u0430\u043a\u043a\u0430\u0443\u043d\u0442 \u0432\u0442\u043e\u0440\u043e\u0433\u043e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6d4\/b42\/0a0\/6d4b420a09addc6d5b32b09be7de5498.png\" width=\"1920\" height=\"912\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6d4\/b42\/0a0\/6d4b420a09addc6d5b32b09be7de5498.png\"\/><\/figure>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0436\u043c\u0435\u043c \u043d\u0430 \u043d\u0438\u043a\u043d\u0435\u0439\u043c \u0438\u043b\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u0432\u0438\u0434\u0438\u043c \u0432 \u0441\u0441\u044b\u043b\u043a\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0441\u0442\u043a\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0438 \u0443\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0435\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/948\/337\/6bb\/9483376bb6e44b3fa86b855a8179ed97.png\" width=\"1804\" height=\"606\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/948\/337\/6bb\/9483376bb6e44b3fa86b855a8179ed97.png\"\/><\/figure>\n<p>\u0418\u0437 \u0432\u0441\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0435\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u044b. \u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \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 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (\u0435\u0433\u043e \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0430\u043a <code>userAdr<\/code>).<\/p>\n<p><strong>P.S: <\/strong>\u041f\u043e\u0432\u0442\u043e\u0440\u044e\u0441\u044c, \u0447\u0442\u043e \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u044e\u0437\u0435\u0440\u043e\u0432.<\/p>\n<pre><code class=\"javascript\">import React, { useEffect, useState } from 'react' import { useParams } from 'react-router-dom'; import '..\/App.css'; import '.\/Profile.css'; import theme from '..\/constants\/colors'; import { useContract } from '..\/contexts\/ContractContext'; import Twitt from '..\/components\/Twitt';  export default function User() {     const { contract, account } = useContract();     const { userAdr } = useParams();     const [user, setUser] = useState();     const [twitts, setTwitts] = useState([]);      useEffect(() => {       if (contract) {           GetUserData();           getUserTwitts();       }     }, [contract]);      const getUserTwitts = async() => {       try {         const twitts = await contract.methods.UserTwitts(userAdr).call({ from: account });          setTwitts(twitts);       } catch (err) {         alert(err);       }     }      const GetUserData = async() => {       try {         const _user = await contract.methods.GetUser(userAdr).call({ from: account });          setUser(_user);       } catch (err) {         alert(err);       }     }      return (       &lt;div className='main'>         &lt;div className='container'            style={{             alignItems: 'start',              justifyContent: 'flex-start',             gap: '5vh'}}>           &lt;div>             &lt;img src={user &amp;&amp; user.avatar ? user.avatar : process.env.PUBLIC_URL + '\/basicProfile.png'} alt=\"avatar\" className='avatar' \/>           &lt;\/div>           &lt;div className='user-info'>             &lt;div style={{marginTop: '5vh'}}>               &lt;h2>Account: &lt;span style={{color: theme.primaryColor}}>{userAdr}&lt;\/span>&lt;\/h2>             &lt;\/div>           &lt;\/div>         &lt;\/div>                  &lt;div className=\"container\" style={{             alignItems: 'start',              justifyContent: 'flex-start',              marginBottom: '5vh',             gap: '5vh'             }}>                      &lt;div className='sidebar'>             {user &amp;&amp; &lt;h2 style={{marginBottom: '4vh'}}>               &lt;span style={{color: 'gray'}}>Username:&lt;\/span>&lt;br\/>@{user.username}             &lt;\/h2>}           &lt;\/div>           &lt;div style={{display: 'flex', flexDirection: 'column', gap: '5vh', width: '80%'}}>             {               twitts.sort((a, b) => Number(b.createdTime) - Number(a.createdTime)).map((twit) => {                 return (                   &lt;Twitt key={twit.createdTime} twit={twit} \/>                 );               })             }           &lt;\/div>         &lt;\/div>        &lt;\/div>     ) } <\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9df\/c89\/5d9\/9dfc895d9550ec876fdf942144b32dd7.png\" alt=\"\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" title=\"\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" width=\"1917\" height=\"909\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9df\/c89\/5d9\/9dfc895d9550ec876fdf942144b32dd7.png\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430. \u041d\u0438\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 <strong>css<\/strong> \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<p><strong>Twitt.css<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"css\">.Twitt {     width: calc(100%-2vh);     height: auto;     padding: 2vh;     padding-top: 0.5vh;     border-color: var(--primary-color);     border-style: groove;     border-width: 2px;     border-radius: 2vh;     display: flex;     flex-direction: column;     justify-content: center;     align-items: start; }  h3, h2 {     text-align: left;     margin: 0;     padding: 0; }  .likes {     margin-top: 4vh;     display: flex;     flex-direction: row;     gap: 1vh;     align-items: center; }  .like {     width: 4vh;     height: 4vh; }  .twitt-pic {     width: 6vh;     height: 6vh; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>Profile.css<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"css\">.avatar {     height: 30vh;     width: 30vh;     border-radius: 3vh; }  .user-info {     height: 30vh;     display: flex;     text-align: left;     flex-direction: column;     justify-content: space-between; }  .edit-btn {     cursor: pointer;     margin-bottom: 5vh;     min-width: 20vh;     width: auto;     max-width: 30vh;     height: 5vh;     color: white;     font-size: 1.2rem;     background-color: var(--primary-color);     border-radius: 2vh;     border-style: none; }  .registration {     display: flex;     align-items: center;     gap: 1.5vh; }  .sidebar {     height: auto;     width: 30vh;      display: flex;     flex-direction: column;      justify-content: left; }  input {     padding-inline: 5px;     outline: none;     height: 5vh;     border-style: inset;     border-color: var(--primary-color);     border-radius: 2vh; }  .add-twitt {     padding: 1vh;     border-style: groove;     border-width: 2px;     border-radius: 10px;     border-color: black;     height: 15vh;     display: flex;     flex-direction: row;     justify-content: space-between; }  .input_twitt {     outline: none;     border-style: none;     width: 90%;     word-wrap: break-word;     resize: none; }  .add-btn {     place-self: center;     cursor: pointer;     width: 15vh;     height: 5vh;     color: white;     font-size: 1.2rem;     background-color: var(--primary-color);     border-radius: 1vh;     border-style: none; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>App.css<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"css\">.App {   text-align: center; }  .App-logo {   height: 40vmin;   pointer-events: none; }  @media (prefers-reduced-motion: no-preference) {   .App-logo {     animation: App-logo-spin infinite 20s linear;   } }  .App-header {   background-color: white;   min-height: 90vh;   display: flex;   flex-direction: column;   align-items: center;   justify-content: center;   font-size: calc(10px + 2vmin);   color: #282c34; }  .App-link {   color: #61dafb; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>index.css<\/strong><\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"css\">:root {   --primary-color: #3366ff; }  body {   margin: 0;   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',     'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',     sans-serif;   -webkit-font-smoothing: antialiased;   -moz-osx-font-smoothing: grayscale; }  code {   font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',     monospace; }  a {   text-decoration: none; }  h2 {   margin: 0; }  .main {   width: 100%;   display: flex;   flex-direction: column;   align-items: center;   justify-content: center; }  .container {   width: 80%;   margin-top: 5vh;   display: flex;   align-items: center;   justify-content: space-between; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0443\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b\u043b\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u0430. <\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/799819\/\"> https:\/\/habr.com\/ru\/articles\/799819\/<\/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<figure class=\"full-width\"><\/figure>\n<p>Hello, \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799407\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0431\u044b\u043b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d backend \u043d\u0430 Solidity, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0438\u0441\u0430\u0442\u044c frontend \u043d\u0430 React.<\/p>\n<blockquote>\n<p>\u041f\u0440\u043e\u0435\u043a\u0442 \u0434\u0430\u043b\u0451\u043a \u043e\u0442 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u043c \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/blockquote>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 <strong>web3,<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0435.<\/p>\n<p><code>$ npx create-react-app client<\/code> <\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438: <code>react-router-dom<\/code>\u0438<code>web3<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c.<\/p>\n<pre><code class=\"bash\">cd client npm i react-router-dom, web3<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 <code>yarn<\/code>:<\/p>\n<pre><code class=\"assembly\">cd client yarn add web3 yarn add react-router-dom<\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043d\u0430\u0448\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <strong>\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong> \u043b\u0438\u0448\u043d\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<figure class=\"\">\n<div><figcaption>\u0423\u0434\u0430\u043b\u044f\u0435\u043c<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0444\u0430\u0439\u043b <strong>index.js <\/strong>\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>BrowserRouter<\/code> \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>react-router-dom<\/code> , \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>App<\/code> \u0432 \u0440\u043e\u0443\u0442\u0435\u0440. \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0447\u0438\u0441\u0442\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0435 \u043f\u0430\u043f\u043a\u0438: <strong>config<\/strong> \u0438 <strong>contexts. <\/strong>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>config <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430: <strong>abi.json <\/strong>(\u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 abi \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430)<strong> <\/strong>\u0438 <strong>contract.js <\/strong>(\u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430).<br \/>P.S: \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 1 \u0431\u043b\u043e\u043a\u0435 \u0432 <code>Ganache<\/code> .<\/p>\n<blockquote>\n<p>ABI &#8212; \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 &#8212; \u044d\u0442\u043e \u043a\u0430\u043a \u0431\u044b \u044f\u0437\u044b\u043a \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438, ABI \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442, \u043a\u0430\u043a \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\u043c\u0438. \u042d\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/blockquote>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 <strong>contexts <\/strong>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <strong>ContractContext.js <\/strong>\u0432 \u043d\u0435\u043c \u043c\u044b \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0443 <code>MetaMask<\/code> \u0438 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u043a \u043d\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u0430\u0439\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u0432 <code>useContract<\/code>.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <strong>contract.js<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u0447\u043a\u0430:<\/p>\n<pre><code class=\"javascript\">export const contract_address = \"\u0430\u0434\u0440\u0435\u0441 \u0432\u0430\u0448\u0435\u0433\u043e \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430\";<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <strong>ABI <\/strong>\u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b <strong>abi.json<\/strong>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 <strong>contracts <\/strong>\u0441 \u043d\u0430\u0448\u0438\u043c \u0431\u044d\u043a\u044d\u043d\u0434\u043e\u043c \u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 <strong>build\/contarcts<\/strong> \u0438 \u0432 \u043d\u0435\u0439 \u0444\u0430\u0439\u043b <strong>Twitter.json. <\/strong>\u0412 \u043d\u0435\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u043c <strong>abi <\/strong>\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0432 \u043d\u0430\u0448 \u0444\u0430\u0439\u043b <strong>abi.json. <\/strong>\u041d\u0438\u0436\u0435 <strong>abi <\/strong>\u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/articles\/799407\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"json\">[     {       \"inputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"constructor\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_username\",           \"type\": \"string\"         },         {           \"internalType\": \"string\",           \"name\": \"_password\",           \"type\": \"string\"         }       ],       \"name\": \"Registration\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_password\",           \"type\": \"string\"         }       ],       \"name\": \"Login\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [],       \"name\": \"Logout\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_text\",           \"type\": \"string\"         }       ],       \"name\": \"AddTwitt\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"UserTwitts\",       \"outputs\": [         {           \"components\": [             {               \"components\": [                 {                   \"internalType\": \"address\",                   \"name\": \"login\",                   \"type\": \"address\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"password\",                   \"type\": \"string\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"username\",                   \"type\": \"string\"                 },                 {                   \"internalType\": \"string\",                   \"name\": \"avatar\",                   \"type\": \"string\"                 }               ],               \"internalType\": \"struct Twitter.User\",               \"name\": \"author\",               \"type\": \"tuple\"             },             {               \"internalType\": \"string\",               \"name\": \"text\",               \"type\": \"string\"             },             {               \"internalType\": \"uint256\",               \"name\": \"likes\",               \"type\": \"uint256\"             },             {               \"internalType\": \"uint256\",               \"name\": \"createdTime\",               \"type\": \"uint256\"             }           ],           \"internalType\": \"struct Twitter.Twitt[]\",           \"name\": \"\",           \"type\": \"tuple[]\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"CheckRegistration\",       \"outputs\": [         {           \"internalType\": \"bool\",           \"name\": \"\",           \"type\": \"bool\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"address\",           \"name\": \"_user\",           \"type\": \"address\"         }       ],       \"name\": \"GetUser\",       \"outputs\": [         {           \"components\": [             {               \"internalType\": \"address\",               \"name\": \"login\",               \"type\": \"address\"             },             {               \"internalType\": \"string\",               \"name\": \"password\",               \"type\": \"string\"             },             {               \"internalType\": \"string\",               \"name\": \"username\",               \"type\": \"string\"             },             {               \"internalType\": \"string\",               \"name\": \"avatar\",               \"type\": \"string\"             }           ],           \"internalType\": \"struct Twitter.User\",           \"name\": \"\",           \"type\": \"tuple\"         }       ],       \"stateMutability\": \"view\",       \"type\": \"function\",       \"constant\": true     },     {       \"inputs\": [         {           \"internalType\": \"string\",           \"name\": \"_avatar\",           \"type\": \"string\"         }       ],       \"name\": \"UpdateUser\",       \"outputs\": [],       \"stateMutability\": \"nonpayable\",       \"type\": \"function\"     }   ]<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0438\u0448\u0435\u043c <code>ContractProvider<\/code> , \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u044b \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 js \u0438 react, \u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u043c.<\/p>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c web3 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u043d\u0430\u0448 \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <strong>abi. <\/strong><\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 <code>ContractContext<\/code>.<\/p>\n<blockquote>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043d\u0438\u0437 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u043f\u0441\u043e\u0432.  <\/p>\n<\/blockquote>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 <code>ContractProvider<\/code> \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439.<\/p>\n<ol>\n<li>\n<p><code>contract <\/code>&#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u043c\u0430\u0440\u0442-\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>account<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<\/li>\n<li>\n<p><code>accounts<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p><code>balance<\/code> &#8212; \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0431\u0430\u043b\u0430\u043d\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432\u043e\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0432 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"javascript\">const [contract, setContract] = useState(null); const [account, setAccount] = useState(null); const [accounts, setAccounts] = useState([]); const [balance, setBalance] = useState();<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0412 \u043d\u0435\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>web3<\/code> \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Ethereum. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u0434\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 <code>MetaMask<\/code> \u0438\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0438 \u043f\u043e\u0440\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0432 <code>Ganache<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>MetaMask<\/code> \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e, \u0442\u043e \u0447\u0435\u0440\u0435\u0437 <code>window.ethereum.request<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u044b \u0438 \u043f\u0435\u0440\u0432\u044b\u0439 ([0]) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>web3.eth.getBalance(accounts[0])<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u0430\u043b\u0430\u043d\u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u0430\u043b\u0430\u043d\u0441\u0430 (\u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0438\u0437 <strong>wei<\/strong> \u0432 <strong>ether<\/strong>) \u0438 \u0431\u0435\u0440\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0435 7 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<pre><code class=\"javascript\">const contractInstance = new web3.eth.Contract(abi, contract_address); setContract(contractInstance);<\/code><\/pre>\n<p>\u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0432 <strong>try-catch <\/strong>\u0434\u043b\u044f \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u043d\u0443\u0442\u0440\u0438 <code>UseEffect<\/code>, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">useEffect(() => {     const initializeContract = async () => {       const web3 = new Web3(Web3.givenProvider || 'http:\/\/127.0.0.1:7545');       if (window.ethereum) {         try {           const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });           if (accounts &amp;&amp; accounts.length > 0) {             setAccounts(accounts);             setAccount(accounts[0]);                const weiBalance = await web3.eth.getBalance(accounts[0]);             const etherBalance = web3.utils.fromWei(weiBalance, 'ether');             setBalance(etherBalance.slice(0, 8));              const contractInstance = new web3.eth.Contract(abi, contract_address);             setContract(contractInstance);           } else {             console.error('No accounts found');           }         } catch (error) {           console.error('Error fetching account balance:', error);         }       } else {         alert('Install MetaMask extension!');       }     };      initializeContract();   }, []);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b\u0435 \u0432 <code>ContractContext.Provider<\/code> \u0438 \u043d\u0430\u0448\u0438 \u0441\u0442\u0435\u0439\u0442\u044b \u0441 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430\u043c\u0438, \u0431\u0430\u043b\u0430\u043d\u0441\u043e\u043c \u0438 \u0442.\u0434.<\/p>\n<pre><code class=\"javascript\">return (     &lt;ContractContext.Provider value={{ contract, account, balance, accounts }}>       {children}     &lt;\/ContractContext.Provider> );<\/code><\/pre>\n<h2>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/h2>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ ContractContext.js import React, { createContext, useContext, useState, useEffect } from 'react'; import Web3 from 'web3'; import { contract_address } from '..\/config\/contract'; import abi from '..\/config\/abi.json';  const ContractContext = createContext();  export const<\/code><\/pre>\n<\/div>\n<\/details>\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-370644","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370644","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=370644"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370644\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}