藤本  結衣

藤本 結衣

1649826986

Web3アプリケーションにおけるSolidityとJavaScriptの役割

技術愛好家またはWeb開発者であるということは、最新の技術とトレンドを常に把握していることを意味します。多くのソフトウェア開発者は、絶え間ない自己開発と改善の方法として個人的なプロジェクトに取り組んでいるため、ブロックチェーン開発、イーサリアム、スマートコントラクト、DApp、SolidityプログラミングなどのWeb3プログラミングの話題の言葉にすでに精通しているかもしれません。

この記事では、これらの用語を深く掘り下げ、ブロックチェーン愛好家や開発者が個人のポートフォリオを強化するために使用できるライブWeb3プロジェクトを構築してホストすることでカバーした内容を固めます。このチュートリアルに従うには、次のものが必要です。

GitHubのクローンを作成して、このチュートリアルで使用されている完全なコードを表示することもできます。始めましょう!

Web3プログラミングとは何ですか?

1989年にTim-BernersLeeによって開発されたWorldWideWebは、  Web1.0から始まりました。読み取り専用Webとして知られるWeb1.0は、基本的に静的Webであり、ユーザーはWeb開発者によって作成されたコンテンツのみを読み取ることができました。基本的な通信モードはHTTPで、WebページはHTMLで開発されました。

2004年以降、Web 2.0は、ユーザーがコンテンツ作成に参加する機会を提供しました。したがって、Web 2.0は、wisdom-webまたは参加型Webと呼ぶことができます。Web 2.0の時代は、Webテクノロジーの分野で大きな発展をもたらしました。たとえば、React、Angular、Vue、XML、CSS3、Tailwind CSS、DOM、TypeScriptなどのいくつかの言語とフレームワークの作成です。

一方、ユーザーとWebテクノロジーアプリケーション間の双方向性を高めることを目的として、新しい標準と古い言語が改善されました。全体として、これにより、ソーシャルメディア、インスタントメッセージング、ブログ、Vlog、ポッドキャスティング、ビデオ共有、チャットなどのさまざまなプラットフォームを介した情報の流れが生まれました。Facebook、Instagram、LinkedIn、YouTubeなどのソーシャルメディアサイトの出現により、グローバルなコミュニケーションと情報共有が実現し、人々がリアルタイムでリモートで作業およびコラボレーションできるようになりました。

Web3、またはセマンティックWebは、このデータのデータ駆動型開発とマシンベースの解釈をもたらしました。この新しいWeb3の時代では、データのプライバシーとデータポリシーが最優先事項です。この懸念は、ブロックチェーンベースの分散化を使用して説明されます。これにより、ユーザーはデータに対する完全な所有権を得ることができます。

さらに、Webテクノロジーは、履歴と使用習慣に基づいて個々のデバイスに合わせてインターネットエクスペリエンスをカスタマイズするため、Web3はユーザーによりパーソナライズされたエクスペリエンスを提供します。これらの機能には、AI、メタバース、パーソナライズされた検索、個人データの制御などがあります。最終的に、Web3では、一元化されたリポジトリが開発されているため、ソーシャルメディアプラットフォームごとに個別のアカウントは必要ありません。

Web3の基本のいくつかを理解したので、Reactを使用してSolidityプロジェクトを構築しましょう。

Reactアプリケーションの構築

このプロジェクトを開始するには、ホスティングサイトを選択し、ドメイン名を購入することをお勧めします。個人的なプロジェクトにお金をかけたくない場合は、Hostinger、Heroku、Netlifyなどのホスティングサイトを試してプロジェクトを展開することができます。

デスクトップにフォルダを作成し、のような名前を付けてweb3.0 project、コードエディタでこのフォルダを開きます。これで、コードエディターで新しいフォルダーを作成し、clientReactアプリケーションを配置する場所に名前を付けることができます。3番目のフォルダーを作成し、名前を変更しますsmartContract。ここに、Solidityコントラクトを記述します。次に、IDEのターミナルで次のコマンドを渡します。

cd .\client\
#or 
cd client

以下のコマンドを渡して、Viteを使用してReactアプリケーションを作成します。これにより、ビルドがインストールされ、わずか数秒でReactアプリケーションが起動します。

npm init vite@latest

Node.jsがデバイスにインストールされていることを確認する必要があります。と言うエラーが発生した場合はtoo many arguments、次のようにコマンドを分離できます。

cd .
client\

上記のコマンドを実行すると、プロジェクトに名前を付けるように求められます。プロジェクトフォルダにいるので./ 、任意のプロジェクト名で使用できます。ここで使いましょうblockchain.json。標準の場合.json、プロジェクト名は1語の小文字の命名規則で始める必要があります。

次に、選択したフレームワーク(この場合はReact)を選択するように求められます。また、2回目のプロンプトが表示されたら、バリアントとしてReactを使用します。これにより、次の画像が表示されます。

選択アプリケーションとしてreactを選択すると、次の画像のようなメッセージプロンプトが表示されます。

npm install

上記のコマンドを渡すと、下の画像のようなものが表示されます。これは、ローカルマシンにReactが正常にインストールされたことを意味します。

npm run dev

上記のコマンドを使用して、Reactアプリケーションをでホストしますport 3000。これで、下の画像と同じ結果が得られるはずです。

ローカルマシンのリンクhttp://localhost:3000をクリックすると、Reactアプリが正常に初期化されていることがわかります。

次に、Tailwind CSSを使用して、CSSコードを別のフォルダーに記述せずにデザインを実装します。Tailwind CSSをインストールするには、次のコマンドを渡します。

npm install -D tailwindcss postcss autoprefixer

次に、以下のコマンドを実行します。

npx tailwindcss init -p

フォルダの作成で問題が発生した場合はtailwind.config.js、次のコマンドを実行してみてください。

npx tailwindcss init
npx tailwindcss-cli@latest init

次に、Postcss.jsローカルマシンのターミナルで次のCLIコマンドを渡してファイルを作成します。

 npm i -D postcss-load-config
 npm i -D postcss-plugin
 npm fund

フォルダに手動でファイルを作成し、src名前を付けることもできますpostcss.config.js。ファイルが正常に作成さpostscss.config.jsれると、次のようなメッセージプロンプトが表示されます。

tailwind.config.js次に、フォルダを次のコードスニペットに置き換えて、Tailwindを構成します。

module.exports = {
  content: ["./src/**/*.{html,js,jsx,ts}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

ファイル内module.exportsのコンテンツセクションには、構成する機能のタイプを説明するために、それぞれHTML、JavaScript、React()、およびTypeScriptが含まれています。将来TypeScriptコマンドを渡す必要がある場合に備えて、TypeScriptを含めます。この場合、ブラウザでコマンドを実行します。tailwind.config.js{html,js,jsx,ts}App.jsxtailwind.config.jsApp.jsxtailwind.config.js

これで、ルート内のindex.cssフォルダー内のすべての値を次の値に置き換えることができます。src

@tailwind base;
@tailwind components;
@tailwind utilities;

App.jsxすべての値をクリアし、それらを以下の値に置き換えることで、フォルダーに対して同じことを行います。

const App = () =>{
  return (
    <div className="App">
    <h1 class="text-3xl font-bold underline">
    My first Blockchain Application!
  </h1>
     </div>
   )
  }
export default App

次に、以下のコマンドを実行して、アプリが機能しているかどうかを確認できます。

npm run dev

以下の画像がブラウザに表示されます。これは、アプリが機能していることを意味します。テキストが太字で下線が引かれていることを確認します。これは、TailwindCSSが期待どおりに実行されていることを示しています。

これで、フロントエンドアプリケーションの構成が完了しました。次に、Reactコンポーネントの構築を開始できます。

Reactコンポーネントの構築

イーサリアムネットワーク上でスマートコントラクトを構築することに焦点を当てます。これを行うには、以下のコマンドを使用して、ローカルマシンの新しいターミナルのフォルダに移動しますcdsmartcontract

cd ..
cd smartContract
npm init -y

上記のコードは、package.jsonファイルの先頭であるファイルを初期化しますsmartContract。フォルダ内のApp.jsxファイルclientは、Webページに表示されるものへの直接のインターフェイスとして機能します。

components次に、フォルダ内にフォルダを作成しsrcます。また、コンポーネントフォルダ内に次のファイルを作成します。

Navbar.jsx

このNavbar.jsxファイルには、機能コンポーネント内のタグ内Navbarに配置されたコンポーネントが含まれています。これについては、すべてのサービスに参加します。後で、いくつかの色でスタイルを設定します。<h1></h1>NavbarNavbarNavbar

const Navbar = () => {
    return (
        <h1>Navbar</h1>
    );
}
export default Navbar;

Footer.jsx

このFooter.jsxファイルには、タグFooter内に配置されたコンポーネントが含まれています。上部の関数と<h1></h1>同じように、ページの下部の関数は次のとおりです。NavbarFooter

const Footer = ()=> {
    return(
        <h1>Footer</h1>
    );
}
export default Footer;

Loader.jsx

Loader.jsxコンポーネントはローディングスピナーとして機能します。

const Loader = ()=> {
    return (
       <h1>Loader</h1>
     );
}
export default Loader;

Services.jsx

このServices.jsxファイルには、サービスを次のようにリストします。

const Services = () =>{
   return (
      <h1>Services</h1>
     );
}
export default Services;

Transactions.jsx

ファイルでは、Transaction.jsxトランザクションを実行します。ユーザーがイーサリアムネットワークを使用してブロックチェーンアプリケーションで複数のトランザクションを実行できるようにするトランザクションサービスを提供します。

const Transactions = () => {
   return (
       <h1>Transactions</h1>
     );
}
export default Transactions;

Welcome.jsx

コンポーネントは、アプリケーションへのwelcome.jsxすべてのユーザーまたは訪問者を歓迎します。ユーザーがインターフェースする最初の連絡先として、welcome.jsxコンポーネントはアプリケーションのフロントページに表示され、フォームやウォレットなど、ランディングページでユーザーに表示されるすべてのフロントエンドディスプレイを収容します。

const Welcome = () => { return ( <h1>Welcome</h1> ); } export default Welcome;

.js.jsxは同義語ですが、jsxReactコードを作成することを示していることに注意してください。

index.js

index.js次に、他のコンポーネントファイルをエクスポートできるようにする最終的なコンポーネントファイルを作成します。次のコードが含まれています。

export { default as Loader } from './Loader';
export { default as Navbar } from './Navbar';
export { default as Services } from './Services';
export { default as Transactions } from './Transactions';
export { default as Footer } from './Footer';
export { default as Welcome } from './Welcome';

Reactコンポーネントのフォーマット

次のコードスニペットをApp.jsxフォルダに含めます。

import {Navbar, Welcome, Footer, Loader, Services,Transactions} from './components';

divこれで、以下の結果を達成するためにフォーマットできます。

import {Navbar, Welcome, Footer, Loader, Services,Transactions} from './components';
const App = () =>{
  return (
    <div className="min-h-screen">
      <div className='gradient-bg-welcome'>
        <Navbar />
        <Welcome />
        </div>
        <Services />
        <Transactions />
        <Footer />
     </div>
   );
  }
export default App;

を実行するnpm run devと、上記と同じ画像が表示されます。次に、以下のコードスニペットをindex.cssファイルに追加して、スタイルを追加します。

@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap");
* html {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  margin: 0;
  font-family: "Open Sans", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.gradient-bg-welcome {
  background-color:#0f0e13;
  background-image: 
    radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%), 
    radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%);
}
.gradient-bg-services {
  background-color:#0f0e13;
  background-image: 
    radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 100%, hsla(225,39%,25%,1) 0, transparent 50%);
}
.gradient-bg-transactions {
  background-color: #0f0e13;
  background-image: 
    radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 0%, hsla(225,39%,25%,1) 0, transparent 50%);
}
.gradient-bg-footer {
  background-color: #0f0e13;
  background-image: 
    radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 53%), 
    radial-gradient(at 50% 150%, hsla(339,49%,30%,1) 0, transparent 50%);
}
.blue-glassmorphism {
  background: rgb(39, 51, 89, 0.4);
  border-radius: 16px;
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  border: 1px solid rgba(0, 0, 0, 0.3);
}
/* white glassmorphism */
.white-glassmorphism {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 16px;
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  border: 1px solid rgba(255, 255, 255, 0.3);
}
.eth-card {
  background-color:#a099ff;
  background-image: 
    radial-gradient(at 83% 67%, rgb(152, 231, 156) 0, transparent 58%), 
    radial-gradient(at 67% 20%, hsla(357,94%,71%,1) 0, transparent 59%), 
    radial-gradient(at 88% 35%, hsla(222,81%,65%,1) 0, transparent 50%), 
    radial-gradient(at 31% 91%, hsla(9,61%,61%,1) 0, transparent 52%), 
    radial-gradient(at 27% 71%, hsla(336,91%,65%,1) 0, transparent 49%), 
    radial-gradient(at 74% 89%, hsla(30,98%,65%,1) 0, transparent 51%), 
    radial-gradient(at 53% 75%, hsla(174,94%,68%,1) 0, transparent 45%);
}
.text-gradient {
  background-color: #fff;
  background-image: radial-gradient(at 4% 36%, hsla(0,0%,100%,1) 0, transparent 53%), radial-gradient(at 100% 60%, rgb(0, 0, 0) 0, transparent 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
@tailwind base;
@tailwind components;
@tailwind utilities;

Navbar上記の値を追加すると、次の画像のようにセクションにカラーグラデーションが表示されます。

npm run dev

image folder次に、の中に配置される新しいにスマートコントラクトのロゴを含めますclient folder。以下のコードスニペットのように、この画像パスをNavbarファイルにインポートし、他のインポートとフォーマットをファイルに含めることで、この画像パスを含めることができます。Nav.jsx

import { HiMenuAlt4 } from 'reacts-icons/hi';
import { AiOutlineClose } from 'react-icons/ai';

import logo from '../../images/logo.png'

ターミナルで以下のコマンドを実行して、Reactアプリケーションが使用するすべての必要な依存関係をインストールしましょう。

npm install react-icons ethers

ethersブロックチェーンとスマートコントラクトを操作できます。

次に、ファイル内にあるロゴ画像を編集するために、ソースをとサイズでNavbar.jsx新しいnav classとを作成します。以下のコードスニペットのように、値を含む順序なしリストを追加します。img{logo}w-40<ul></ul>className

 <nav className='w-full flex md: justify-center justify-between items-center p-4'>
            <div className='md: flex-[0.5] flex-initial justify-center items-center'>
                <img src= {logo} alt="logo" className='w-40 cursor-pointer'/>
            </div>
            <ul className='text-white md:flex hidden list-none 
            flex-row justify-betwen items-center flex-initial'>
            </ul>
        </nav>

次に、新しい機能コンポーネントを作成し、次のNavbarItemようないくつかの小道具を設定しtitle ますclassProps

const NavbarItems = ({title, classProps }) =>{
    return (
        <li className={`mx-4 cursor-pointer ${classProps}`}>
            {title}
        </li>
    );
}

NavbarItemこれで、関数内で再利用可能なコンポーネントとしてを呼び出しNavbar、新しい動的配列ブロックを作成できます。

{["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/> )}

関数内Navbarには、次のコードがあります。

ul className='text-white md:flex hiddent list-none flex-row justify-betwen items-center flex-initial'>
{["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/>))}

次に、次のコードスニペットを使用してアプリケーションのログインボタンを作成します。

<li className='bg-[#2952e3] py-2 px-7 mx-4 rounded-full cursor-pointer hover:bg-[#2546bd]' >
Login
</li>

レスポンシブデザインの確保

NavbarモバイルデバイスとWebデバイスの両方でユーザーのディスプレイが同じになるように、レスポンシブデザインを実現したいと考えています。これを実現するために、Reactstateを導入します。これはtoggleMenu, setToggleMenu、モバイルNavbarが現在開いているときに特定のアクションを実行します。

const Navbar = () => {
    const [toggleMenu, setToggleMenu] = useState(false);
    return (
        <nav className='w-full flex md: justify-center justify-between items-center p-4'>
            <div className='md: flex-[0.5] flex-initial justify-center items-center'>
                <img src= {logo} alt="logo" className='w-40 cursor-pointer'/>
            </div>
            <ul className='text-white md:flex hiddent list-none flex-row justify-betwen items-center flex-initial'>
                  {["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/>))}

                 <li className='bg-[#2952e3] py-2 px-7 mx-4 rounded-full cursor-pointer hover:bg-[#2546bd]' >
                     Login
                 </li>
            </ul>
            <div className="flex relative">
                {toggleMenu
                ? <AiOutlineClose fontSize={28} className="text-white md:hidden cursor-pointer" onClick={()=>setToggleMenu(false)} /> 
                : <HiMenuAlt4 fontSize={28} className="text-white md:hidden cursor-pointer" onClick={()=>setToggleMenu(true)} />
                }
                {toggleMenu && (
                    <ul>
                        <li className='text-xl w-full my-2'>
                            <AiOutlineClose onClick={()=> setToggleMenu(false)} />
                        </li>
                        {["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item} classProps ="my-2 text-lg" />))}
                    </ul>
                )}
            </div>
        </nav>
    );
}
export default Navbar;

ブラウザに移動し、 [検査]を右クリックして、モバイルビューに移動します。以下と同じ画像が必要です。

上の画像から、デスクトップビューとモバイルビューの両方を表示できます。次に、コンポーネントに取り組みwelcome.jsx、いくつかの新しいものdivclassNames:を含めましょう。

 <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on crypto our wallet
                    </p>

コンポーネントには、以下のwelcome.jsxコードが含まれています。

import { AiFillAlipayCircle } from "react-icons/ai";
import { SiEthereum } from "react-icons/si";
import { BsInfoCircle }  from "react-icons/bs";
import { Loader } from './';
const commonStyles = () => 'min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white';
const Welcome = () => {

    const connectWallet = () => {
    }
    return (
        <div className="flex w-full justify-center items-center">
            <div className="flex md:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">
                <div className="flex flex-1 justify-start flex-col md:mr-10">
                    <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on crypto our wallet
                    </p>
                    <button type="button" onClick={connectWallet} className="flex flex-row justify-center items-center my-5 bg-[#2952e3] p-3 rounded-full cursor-pointer">
                        <p className= "text-white text-base font-semibold">
                        Connect Wallet
                        </p> 
                    </button>
                      <div className="grid sm:grid-cols-3 grid-cols-2 w-full mt-10">
                        <div className={`rounded-tl-2xl ${commonStyles} text-white`}>
                           Reliability
                        </div>
                       <div className={`rounded-th-2xl ${commonStyles} text-white`}>
                           Security
                        </div>
                       <div className={`rounded-tr-2xl ${commonStyles} text-white`}>
                           Ethereum
                       </div>
                       <div className={`rounded-bl-2xl ${commonStyles} text-white`}>
                           Web 3.0
                        </div>
                       <div className={`rounded-bh-2xl ${commonStyles} text-white`}>
                           Low fees
                        </div>
                       <div className={`rounded-br-2xl ${commonStyles} text-white`}>
                           Blockchain
                        </div>
                     </div>
                </div>
                <div className="flex flex-col flex-1 items-center justify-start w-full md:mt-0 mt-10">
                    <div className="p-3 justify items-start flex-col rounded-xl h-40 sm:w-72 w-full my-5 eth-card white-glassmorphism">
                        <div className="flex justify-between">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}
export default Welcome;

上記のコードベースは、以下の画像になります。私たちはいくつかdivの余分なものを含めて、それらにユニークclassNamesで、properties以下の私たちのデザインに合うように与えました:

次に、Ethereum下の画像に同じデザインのカードを追加しました。 また、ユーザーからの入力を収集するのに役立つボタンformsend Nowボタンをコンポーネントに追加しました。welcome.jsx

<Input placeholder= "Address To" name = "addressTo" type="text" handleChange={()=>{}} />
                            <Input placeholder= "Amount (ETH)" name = "amount" type="number" handleChange={()=>{}} />
                            <Input placeholder= "Keyword (gif)" name = "keyword" type="text" handleChange={()=>{}} />
                            <Input placeholder= "Enter Message" name = "message" type="text" handleChange={()=>{}} />

完全なwelcome.jsx コンポーネントのコードベースと結果を以下に示します。

ディスプレイの改善

より良い表示を実現するためにに変更することで、コードにいくつかの変更を加えmdます。mfこれらの変更は、以下のコードスニペットのクラスに実装されています。

mf:flex-row

<div className="flex mf:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">

mf:mr-1

- <div className="flex flex-1 justify-start flex-col mf:mr-10">

mf:mt-0 mt-10">

<div className="flex flex-col flex-1 items-center justify-start w-full mf:mt-0 mt-10">

tailwind.cssそれでは、ファイルのコードベースを次のコードベースに置き換えて、ファイルにいくつかの変更を加えましょうtailwind.config.js

 module.exports = {
  purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],
  mode: "jit",
  darkMode: false, // or 'media' or 'class'
  theme: {
    fontFamily: {
      display: ["Open Sans", "sans-serif"],
      body: ["Open Sans", "sans-serif"],
    },
    extend: {
      screens: {
        mf: "990px",
      },
      keyframes: {
        "slide-in": {
          "0%": {
            "-webkit-transform": "translateX(120%)",
            transform: "translateX(120%)",
          },
          "100%": {
            "-webkit-transform": "translateX(0%)",
            transform: "translateX(0%)",
          },
        },
      },
      animation: {
        "slide-in": "slide-in 0.5s ease-out",
      },
    },
  },
  variants: {
    extend: {},
  },
  plugins: [require("/Users/peter/Dropbox/Mac/Desktop/web3.0/client/tailwind.config.js")],
};

上記のコードスニペットを使用する場合は、自分がいるpluginsローカルマシンで必要なパスに変更してくださいtailwind.config.js

plugins: [require("/Users/peter/Dropbox/Mac/Desktop/web3.0/client/tailwind.config.js")]

これで、フロントエンドの設計とReactアプリケーションが正常に完了しました。それでは、スマートコントラクトの構築を始めましょう。

Reactアプリケーションをブロックチェーンに接続する

smartContractフォルダ内のターミナルで以下のコードスニペットを実行して、依存関係をインストールします。

cd smartContract
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers

スマートコントラクトの基本構造を作成するために、専門家向けのイーサリアム開発環境であるHardhatを使用します。また、Solidityを実行し、展開前にスマートコントラクトを1回テストすることもできます。インストールが正常に完了すると、次のようなプロンプトが表示されます。

以下のコマンドを実行します。

npx hardhat

エンターボタンをクリックして基本的なサンプルプロジェクトを作成し、プロンプトが表示さ.gitignoreれたらクリックして追加します。y

contractを含むフォルダとフォルダGreeter.solがあることがわかりtestます。すべてが正常に機能していることを確認するには、次のコマンドを渡します。

npx hardhat test

次に、VS CodeエディターからSolidity拡張機能を検索し、エディターにインストールして、構文とオートコンプリート機能を支援します。

Solidityを使用してEthereumネットワークでスマートコントラクトを作成する

Greeter.solHardhatによってデフォルトで作成されたコントラクトを削除します。その後、新しいファイルを作成して名前を変更することで、独自のコントラクトを作成できますTransactions.sol.sol接尾辞はSolidityを表します。Solidityプログラミング言語は、Java、JavaScript、Rust、C++などのいくつかの言語を組み合わせたものです。

次に、以下のコードスニペットに従って、使用するSolidityのバージョンを選択します。licenseバージョンの上のコメントに必ず含めてください。

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

これで、を作成しcontract、ファイルのタイトルと同じ名前を付けて、クラスinteger内で変数を宣言できます。Transactionこの変数を使用してトランザクションを保持し、この変数に名前を付けますtransactionCounter

eventと呼ばれるを作成しますTransfer。このイベントは、、、、などのTransferパラメータを受け入れる関数のようなものです。完了する各転送には、次のプロパティが必要です。address fromaddress receiveramounttimestamp

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Transactions {
    uint256 transactionCounter;
    event Transfer (address from, address receiver, uint amount, string message, uint256 timestamp, string keyword);
    struct TransferSystem{
        address sender;
        address receiver;
        uint amount;
        string message;
        uint256 timestamp;
        string keyword;
    }
}

トランザクションを保存するために、タイプが。のトランザクションの配列を定義できますTransferSystemaddToBlockchainまた、、、、など、実行されるアクションを説明する命名規則を使用していくつかの関数を定義しgetAllTransactionsますgetTransactionCount

  TransferSystem [] transactions;

    function addToBlockchain(address payable receiver, uint amount, string memory message, string memory keyword) public{

    }
    function getAllTransactions() public view returns (TransferSystem[] memory){
    }
    function getTransactionCount() public view returns (uint256){
    }

このaddToBlockchain関数では、を1つインクリメントし、transactionCountパラメーターをプッシュしてから出力します。

function addToBlockchain(address payable receiver, uint amount, string memory message, string memory keyword) public{
        transactionCount +=1;
        transactions.push(TransferSystem(msg.sender, receiver, amount, message, block.timestamp, keyword));
        emit Transfer(msg.sender, receiver, amount, message, block.timestamp, keyword);
    }

このgetAllTransactions関数では、次を返しますtransactions

function getAllTransactions() public view returns (TransferSystem[] memory){
        return transactions;
    }

このgetTransactionsCount関数では、次を返しますtransactionCount

function getTransactionCount() public view returns (uint256){
        return transactionCount;
    }

これで、EthereumSolidityスマートコントラクトが完成しました。

Web3アプリケーションのデプロイ

スマートコントラクトをデプロイするにscriptは、VS Codeエディターに移動しsample-script.js、をクリックして名前を変更しdeploy.jsます。mainトランザクションのデプロイに役立つ関数を作成して、このファイルを編集します。また、デフォルトのGreeter定数をTransaction次のように変更します。

const main = async () => {
  const Transactions = await ethers.getContractFactory("Transactions");
  const transactions = await Transactions.deploy();
  await transactions.deployed();
  console.log("Transactions deployed to: ", transactions.address);
}
const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
}
runMain ();

上記のコードスニペットは、トランザクションをブロックチェーンウォレットにデプロイするのに役立ちます。しかし、そうするためには、すでにイーサリアムまたはガスが必要です。ガスとは、取引を行うために必要なエーテルの一部を指します。Ropsten Testnet Faucetにアクセスして、テストイーサリアムを入手できます。ウォレットアドレスも提供する必要があります。このために、ブラウザでMetamask拡張機能を設定する必要があります。

これで、 show test networkのトグルを変更して、EthereumMainnetでテストネットワークを有効にできます。

右上隅で、EthereumMainnetをRopstenTestNetworkに変更できます。

これで、アカウント1からアカウントアドレスをコピーして、RopstenTestFaucetに貼り付けることができます。

ブロックチェーンをデプロイするには、Alchemyに移動します。ここでのネットワークの選択はRopstenになることに注意してください。これにより、実際のイーサリアムガス料金を支払うことができなくなります。

Alchemyでアカウントを正常に作成したら、右上隅にある[アプリの作成]をクリックして、希望する詳細を入力します。次に、ビューキーをクリックして、HTTPキーをコピーします。

これで、プラグインとしてhardhat.config.js使用してスマートコントラクトをテストするために戻ることができます。以下のコードのようにhardhat-waffles編集する必要があります。hardhat.config.js

require('@nomiclabs/hardhat-waffle');
module.exports = {
  solidity : '0.8.0',
  networks : {
    ropsten:{
      url: `https://eth-ropsten.alchemyapi.io/v2/SFRRwFrEK3nQkYAis0Z0dBLjcWEHtztJ`,
      accounts: ['085164c615a0edb827a8ee5c1759b7c704bc519130841121ad07b21aff359929']
    } 
  }
}

このhardhat.config.jsフォルダーでは、上記で生成された秘密鍵をアカウントに割り当てましたが、URLはAlchemyからのHTTPです。アプリケーションをデプロイするには、に移動してterminal次のコマンドを入力します。

npx hardhat run scripts/deploy.js --network ropsten

次の画像のように、生成された住所番号を取得します。

次に、に移動し、client folderを右クリックしてsrc、という名前の新しいフォルダを作成しますutils。フォルダ内にutil、という新しいファイルを作成し、constant.js以下のコードスニペットを使用して生成されたアドレスを入力できます。

export const contractAddress= `0x02207Ac5b9ffc1d8BFc242ad3BAB1A44Ebc7D9bb`;

→→→→にsmartContract進みます。artifact_ アプリケーションバイナリインターフェイスを意味するABIは、イーサリアムシステムのスマートコントラクトと対話するための標準的な方法です。Transactions.solTransactions.jsonabi

次に、すべてをコピーしてから、フォルダTransactions.json内に作成する新しいファイルに貼り付けます。utilsこの新しいファイルに名前を付けることができますTransactions.jsonconstants.js以下のコードスニペットを使用して、これをフォルダにインポートしましょう。

import abi from `./Transactions.json`;
export const contractABI = abi.abi;
export const contractAddress = `0x02207Ac5b9ffc1d8BFc242ad3BAB1A44Ebc7D9bb`;

次に、srcという名前のフォルダーとcontext、という名前のファイルを作成します。これにより、アプリケーション全体でReactContextAPITransactionContext.jsxを使用できるようになります。

import React, {useEffects, useState} from 'react';
import { ethers } from 'ethers';
import { contractABI, ContractABI, contractAddress } from '../util/constants';
export const TransactionContext = React.createContext();
const { ethereum } = window;
const getEthereumContract = () => {
    const provider = new ethers.provider.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);

    console.log({
        provider,
        signer,
        transactionContract
    });
}
export const transactionProvider = ( children ) => {
    return (
        <TransactionContext.Provider value={{value: 'test'}}>
            {children}
        </TransactionContext.Provider>
    );
}

また、以下のコードスニペットのようにファイルにインポートTransactionContextします。main.jsx

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import TransactionContext from './context/TransactionContext'
ReactDOM.render(
  <TransactionProvider>

  <React.StrictMode>
    <App />
  </React.StrictMode>
  </TransactionProvider>,
  document.getElementById('root')
)

TransactionContext.jsx以下で共有するのコードスニペットにいくつかの変更を加えました。

import React, {useEffect, useState} from 'react';
import { ethers } from 'ethers';
import { contractABI, contractAddress } from '../util/constants';
export const TransactionContext = React.createContext();
const { ethereum } = window;
const getEthereumContract = () => {
    const provider = new ethers.provider.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);

   return transactionContract;
}
export const TransactionProvider = ({children}) => {
     const [currentAccount, setCurrentAccount] = useState('');
     const [formData, setFormData] = useState({addressTo: '', amountTo: '', keyword: '', message: ''});
     const [isLoading, setIsLoading] = useState(false);
     const [transactionCount, setTransaction] = useState(localStorage.getItem('transactionCount'));
     const handleChange = (e, name) => {
         setFormData((prevState) => ({ ...prevState, [name]: e.target.value }));
     }
      const checkIfWalletIsConnected = async () => {

    try{
        if (!ethereum) return alert ("Please install metamask!");
        const accounts = await ethereum.request({ method: 'eth_accounts'});
        if(accounts.length){
            setCurrentAccount(accounts[0]);
        }
        else{
            console.log("No accout found!");
        }
        console.log(accounts);
      } catch(error) {

        throw new Error("No ethereum object...");
    }
  }    
      const connectWallet = async () => {
          try {
            if (!ethereum) return alert ("Please install metamask!");
            const accounts = await ethereum.request({ method: 'eth_requestAccounts'});
            setCurrentAccount(accounts[0]);
          } catch (error) {
              console.log(error);
              throw new Error("No ethereum object...");
          }
      }
      const sendTransaction = async () => {
          try {
            if (!ethereum) return alert ("Please install metamask!");
            const {addressTo, amount, keyword, message} = formData;
            const transactionContract = getEthereumContract();
            const parsedAmount = ethers.utils.parsedEther(amount);
            await ethereum.request({ 
                method: 'eth_sendTransactions',
                params: [{
                from: currentAccount,
                to: addressTo, 
                gas: '0x5208',
                vaue: parsedAmount._hex,    
                }]
            });
           const transactionHash = await transactionContract.addToBlockchain(addressTo,parsedAmount,message,keyword);

           setIsLoading(true);
           console.log(`Loading - ${transactionHash.hash}`);
           await transactionHash.wait();
           setIsLoading(false);
           console.log(`Success - ${transactionHash.hash}`);
           const transactionCount = await transactionContract.getTransactionCount();
           setTransactionCount(transactionCount.toNumber());
          } catch (error) {
            console.log(error);
            throw new Error("No ethereum object...");
          }
      }
     useEffect(()=> {
        checkIfWalletIsConnected();
     },[]);
    return (
        <TransactionContext.Provider value={{connectWallet, currentAccount,formData,setFormData,handleChange, sendTransaction}}>
            {children}
        </TransactionContext.Provider>
    );
   }

 

Welcome.jsx以下のコードは、コンポーネントに加えられたすべての追加の変更を示しています。

import { AiFillAlipayCircle } from "react-icons/ai";
import { SiEthereum } from "react-icons/si";
import { BsInfoCircle }  from "react-icons/bs";
import { TransactionContext } from "../context/TransactionContext";
import React, { useContext } from 'react';
import { Loader } from './';
const Input = ({placeholder, name, type, value, handleChange}) => (
    <input
    placeholder={placeholder}
    type={type}
    step= "0.0001"
    value={value}
    onChange={(e)=>handleChange(e,name)}
    className= "my-2 w-full rounded-sm p-2 outline-none bg-transparent text-white border-none text-sm white-glassmorphism"
    />
);
const commonStyles = () => 'min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white';
const Welcome = () => {
    const { connectWallet, currentAccount, formData, sendTransaction, handleChange } = useContext(TransactionContext);
    const handleSubmit = (e) => {
        const {addressTo, amount, keyword, message} = formData;

        e.preventDefault();
        if(!addressTo || !amount ||  !keyword || !message) return;
        sendTransaction();
    }
    return (
        <div className="flex w-full justify-center items-center">
            <div className="flex mf:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">
                <div className="flex flex-1 justify-start flex-col mf:mr-10">
                    <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on our crypto wallet
                    </p>
                    {!currentAccount && (<button type="button" onClick={connectWallet} className="flex flex-row justify-center items-center my-5 bg-[#2952e3] p-3 rounded-full cursor-pointer">

                        <p className= "text-white text-base font-semibold">Connect Wallet</p> 
                    </button>)}
                      <div className="grid sm:grid-cols-3 grid-cols-2 w-full mt-10">
                        <div className={`rounded-tl-2xl ${commonStyles} text-white`}>
                           Reliability
                        </div>
                       <div className={`rounded-th-2xl ${commonStyles} text-white`}>
                           Security
                        </div>
                       <div className={`rounded-tr-2xl ${commonStyles} text-white`}>
                           Ethereum
                       </div>
                       <div className={`rounded-bl-2xl ${commonStyles} text-white`}>
                           Web 3.0
                        </div>
                       <div className={`rounded-bh-2xl ${commonStyles} text-white`}>
                           Low fees
                        </div>
                       <div className={`rounded-br-2xl ${commonStyles} text-white`}>
                           Blockchain
                        </div>
                     </div>
                </div>
                <div className="flex flex-col flex-1 items-center justify-start w-full mf:mt-0 mt-10">
                    <div className="p-3 justify-end items-start flex-col rounded-xl h-40 sm:w-72 w-full my-5 eth-card white-glassmorphism">
                        <div className="flex justify-between flex-col w-full h-full">
                            <div className="flex justify-between items-start">
                                <div className="w-10 h-10 rounded-full border-2 border-white flex justify-center items-center">
                                    <SiEthereum fontSize={21} color="#fff" />
                                </div>
                                <BsInfoCircle fontSize={17} color="#fff"/>
                                </div>
                                <div>
                                <p className="text-white font-light text-sm">
                                 Address (0Xapdpqdf.......fdsb)
                                </p>
                                <p className="text-white font-light text-white font-semibold text-lg mt-1">
                                    ETHEREUM
                                </p>
                             </div>
                            </div>
                        </div>
                        <div className="p-5 sm:w-96 flex-full flex flex-col justify-start items-center blue-glassmorphism">

                            <Input placeholder= "Address To" name = "addressTo" type="text" handleChange={handleChange} />
                            <Input placeholder= "Amount (ETH)" name = "amount" type="number" handleChange={handleChange} />
                            <Input placeholder= "Keyword (gif)" name = "keyword" type="text" handleChange={handleChange} />
                            <Input placeholder= "Enter Message" name = "message" type="text" handleChange={handleChange} />
                            <div className="h-[1px] w-full bg-gray-400 my-2" />
                            {false ?(
                                <Loader />
                            ): (
                                <button
                                type="button"
                                onClick={handleSubmit}
                                className="text-white w-full mt-2 border-[1px] p-2 border-[#3d4f7c] rounded-full cursor-pointer">
                                    Send Now
                                </button>
                            )}
                        </div>
                </div>
            </div>
        </div>
    );
}
export default Welcome;

それでは、先に進んでアプリケーションをテストしましょう。

Web3アプリケーションのテスト

アプリケーションをテストするために、Metamaskを開いて新しいアカウントを作成し、別のアドレスを生成して送金することができます。

2つ目のアカウントが正常に作成されたら、アドレスをコピーaddressToしてブラウザページに貼り付け、送信するイーサリアムの量を選択し、キーワードまたはメッセージを渡して、[今すぐ送信 ]ボタンをクリックします。

アプリケーションを再起動した後、ウォレットに接続ボタンをクリックして、Metamaskに再度接続する必要があることに注意してください。トランザクションを完了する前に、次のことを行ってください。

イーサを送る

イーサを受け取る

完成したプロジェクトをYouTubeでチェックすることもできます。

結論

この記事では、Web3アプリケーションを最初から作成することに成功しました。Solidityプログラミング言語を使用してアプリケーションを構築するために深く掘り下げる前に、Web3テクノロジーの紹介から始めました。次に、アプリケーションをテストし、ブロックチェーントランザクションを実行しました。

この記事全体を通して、SolidityとJavaScriptがスマートコントラクトの開発において果たす大きな役割を観察してきました。Reactを使用して、、などのいくつかのコンポーネントを使用してスマートコントラクトのフロントエンドを開発し、Solidityを使用してLoaderスマートwelcomeコントラクトを構築しました。この記事で概説されている手順に従って、Ethereumネットワーク上で最初のスマートコントラクトを構築できます。

この記事がお役に立てば幸いです。Web3をどのように改善できるかについてのご意見をお聞かせください。質問や懸念がある場合は、コメントを残してください。あなたのプロジェクトを楽しみにしています。ハッピーコーディング!

ソース:https ://blog.logrocket.com/solidity-javascript-web3-blockchain-applications/ 

 #javascript #solidity #web3 #blockchain #applications 

What is GEEK

Buddha Community

Web3アプリケーションにおけるSolidityとJavaScriptの役割
藤本  結衣

藤本 結衣

1649826986

Web3アプリケーションにおけるSolidityとJavaScriptの役割

技術愛好家またはWeb開発者であるということは、最新の技術とトレンドを常に把握していることを意味します。多くのソフトウェア開発者は、絶え間ない自己開発と改善の方法として個人的なプロジェクトに取り組んでいるため、ブロックチェーン開発、イーサリアム、スマートコントラクト、DApp、SolidityプログラミングなどのWeb3プログラミングの話題の言葉にすでに精通しているかもしれません。

この記事では、これらの用語を深く掘り下げ、ブロックチェーン愛好家や開発者が個人のポートフォリオを強化するために使用できるライブWeb3プロジェクトを構築してホストすることでカバーした内容を固めます。このチュートリアルに従うには、次のものが必要です。

GitHubのクローンを作成して、このチュートリアルで使用されている完全なコードを表示することもできます。始めましょう!

Web3プログラミングとは何ですか?

1989年にTim-BernersLeeによって開発されたWorldWideWebは、  Web1.0から始まりました。読み取り専用Webとして知られるWeb1.0は、基本的に静的Webであり、ユーザーはWeb開発者によって作成されたコンテンツのみを読み取ることができました。基本的な通信モードはHTTPで、WebページはHTMLで開発されました。

2004年以降、Web 2.0は、ユーザーがコンテンツ作成に参加する機会を提供しました。したがって、Web 2.0は、wisdom-webまたは参加型Webと呼ぶことができます。Web 2.0の時代は、Webテクノロジーの分野で大きな発展をもたらしました。たとえば、React、Angular、Vue、XML、CSS3、Tailwind CSS、DOM、TypeScriptなどのいくつかの言語とフレームワークの作成です。

一方、ユーザーとWebテクノロジーアプリケーション間の双方向性を高めることを目的として、新しい標準と古い言語が改善されました。全体として、これにより、ソーシャルメディア、インスタントメッセージング、ブログ、Vlog、ポッドキャスティング、ビデオ共有、チャットなどのさまざまなプラットフォームを介した情報の流れが生まれました。Facebook、Instagram、LinkedIn、YouTubeなどのソーシャルメディアサイトの出現により、グローバルなコミュニケーションと情報共有が実現し、人々がリアルタイムでリモートで作業およびコラボレーションできるようになりました。

Web3、またはセマンティックWebは、このデータのデータ駆動型開発とマシンベースの解釈をもたらしました。この新しいWeb3の時代では、データのプライバシーとデータポリシーが最優先事項です。この懸念は、ブロックチェーンベースの分散化を使用して説明されます。これにより、ユーザーはデータに対する完全な所有権を得ることができます。

さらに、Webテクノロジーは、履歴と使用習慣に基づいて個々のデバイスに合わせてインターネットエクスペリエンスをカスタマイズするため、Web3はユーザーによりパーソナライズされたエクスペリエンスを提供します。これらの機能には、AI、メタバース、パーソナライズされた検索、個人データの制御などがあります。最終的に、Web3では、一元化されたリポジトリが開発されているため、ソーシャルメディアプラットフォームごとに個別のアカウントは必要ありません。

Web3の基本のいくつかを理解したので、Reactを使用してSolidityプロジェクトを構築しましょう。

Reactアプリケーションの構築

このプロジェクトを開始するには、ホスティングサイトを選択し、ドメイン名を購入することをお勧めします。個人的なプロジェクトにお金をかけたくない場合は、Hostinger、Heroku、Netlifyなどのホスティングサイトを試してプロジェクトを展開することができます。

デスクトップにフォルダを作成し、のような名前を付けてweb3.0 project、コードエディタでこのフォルダを開きます。これで、コードエディターで新しいフォルダーを作成し、clientReactアプリケーションを配置する場所に名前を付けることができます。3番目のフォルダーを作成し、名前を変更しますsmartContract。ここに、Solidityコントラクトを記述します。次に、IDEのターミナルで次のコマンドを渡します。

cd .\client\
#or 
cd client

以下のコマンドを渡して、Viteを使用してReactアプリケーションを作成します。これにより、ビルドがインストールされ、わずか数秒でReactアプリケーションが起動します。

npm init vite@latest

Node.jsがデバイスにインストールされていることを確認する必要があります。と言うエラーが発生した場合はtoo many arguments、次のようにコマンドを分離できます。

cd .
client\

上記のコマンドを実行すると、プロジェクトに名前を付けるように求められます。プロジェクトフォルダにいるので./ 、任意のプロジェクト名で使用できます。ここで使いましょうblockchain.json。標準の場合.json、プロジェクト名は1語の小文字の命名規則で始める必要があります。

次に、選択したフレームワーク(この場合はReact)を選択するように求められます。また、2回目のプロンプトが表示されたら、バリアントとしてReactを使用します。これにより、次の画像が表示されます。

選択アプリケーションとしてreactを選択すると、次の画像のようなメッセージプロンプトが表示されます。

npm install

上記のコマンドを渡すと、下の画像のようなものが表示されます。これは、ローカルマシンにReactが正常にインストールされたことを意味します。

npm run dev

上記のコマンドを使用して、Reactアプリケーションをでホストしますport 3000。これで、下の画像と同じ結果が得られるはずです。

ローカルマシンのリンクhttp://localhost:3000をクリックすると、Reactアプリが正常に初期化されていることがわかります。

次に、Tailwind CSSを使用して、CSSコードを別のフォルダーに記述せずにデザインを実装します。Tailwind CSSをインストールするには、次のコマンドを渡します。

npm install -D tailwindcss postcss autoprefixer

次に、以下のコマンドを実行します。

npx tailwindcss init -p

フォルダの作成で問題が発生した場合はtailwind.config.js、次のコマンドを実行してみてください。

npx tailwindcss init
npx tailwindcss-cli@latest init

次に、Postcss.jsローカルマシンのターミナルで次のCLIコマンドを渡してファイルを作成します。

 npm i -D postcss-load-config
 npm i -D postcss-plugin
 npm fund

フォルダに手動でファイルを作成し、src名前を付けることもできますpostcss.config.js。ファイルが正常に作成さpostscss.config.jsれると、次のようなメッセージプロンプトが表示されます。

tailwind.config.js次に、フォルダを次のコードスニペットに置き換えて、Tailwindを構成します。

module.exports = {
  content: ["./src/**/*.{html,js,jsx,ts}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

ファイル内module.exportsのコンテンツセクションには、構成する機能のタイプを説明するために、それぞれHTML、JavaScript、React()、およびTypeScriptが含まれています。将来TypeScriptコマンドを渡す必要がある場合に備えて、TypeScriptを含めます。この場合、ブラウザでコマンドを実行します。tailwind.config.js{html,js,jsx,ts}App.jsxtailwind.config.jsApp.jsxtailwind.config.js

これで、ルート内のindex.cssフォルダー内のすべての値を次の値に置き換えることができます。src

@tailwind base;
@tailwind components;
@tailwind utilities;

App.jsxすべての値をクリアし、それらを以下の値に置き換えることで、フォルダーに対して同じことを行います。

const App = () =>{
  return (
    <div className="App">
    <h1 class="text-3xl font-bold underline">
    My first Blockchain Application!
  </h1>
     </div>
   )
  }
export default App

次に、以下のコマンドを実行して、アプリが機能しているかどうかを確認できます。

npm run dev

以下の画像がブラウザに表示されます。これは、アプリが機能していることを意味します。テキストが太字で下線が引かれていることを確認します。これは、TailwindCSSが期待どおりに実行されていることを示しています。

これで、フロントエンドアプリケーションの構成が完了しました。次に、Reactコンポーネントの構築を開始できます。

Reactコンポーネントの構築

イーサリアムネットワーク上でスマートコントラクトを構築することに焦点を当てます。これを行うには、以下のコマンドを使用して、ローカルマシンの新しいターミナルのフォルダに移動しますcdsmartcontract

cd ..
cd smartContract
npm init -y

上記のコードは、package.jsonファイルの先頭であるファイルを初期化しますsmartContract。フォルダ内のApp.jsxファイルclientは、Webページに表示されるものへの直接のインターフェイスとして機能します。

components次に、フォルダ内にフォルダを作成しsrcます。また、コンポーネントフォルダ内に次のファイルを作成します。

Navbar.jsx

このNavbar.jsxファイルには、機能コンポーネント内のタグ内Navbarに配置されたコンポーネントが含まれています。これについては、すべてのサービスに参加します。後で、いくつかの色でスタイルを設定します。<h1></h1>NavbarNavbarNavbar

const Navbar = () => {
    return (
        <h1>Navbar</h1>
    );
}
export default Navbar;

Footer.jsx

このFooter.jsxファイルには、タグFooter内に配置されたコンポーネントが含まれています。上部の関数と<h1></h1>同じように、ページの下部の関数は次のとおりです。NavbarFooter

const Footer = ()=> {
    return(
        <h1>Footer</h1>
    );
}
export default Footer;

Loader.jsx

Loader.jsxコンポーネントはローディングスピナーとして機能します。

const Loader = ()=> {
    return (
       <h1>Loader</h1>
     );
}
export default Loader;

Services.jsx

このServices.jsxファイルには、サービスを次のようにリストします。

const Services = () =>{
   return (
      <h1>Services</h1>
     );
}
export default Services;

Transactions.jsx

ファイルでは、Transaction.jsxトランザクションを実行します。ユーザーがイーサリアムネットワークを使用してブロックチェーンアプリケーションで複数のトランザクションを実行できるようにするトランザクションサービスを提供します。

const Transactions = () => {
   return (
       <h1>Transactions</h1>
     );
}
export default Transactions;

Welcome.jsx

コンポーネントは、アプリケーションへのwelcome.jsxすべてのユーザーまたは訪問者を歓迎します。ユーザーがインターフェースする最初の連絡先として、welcome.jsxコンポーネントはアプリケーションのフロントページに表示され、フォームやウォレットなど、ランディングページでユーザーに表示されるすべてのフロントエンドディスプレイを収容します。

const Welcome = () => { return ( <h1>Welcome</h1> ); } export default Welcome;

.js.jsxは同義語ですが、jsxReactコードを作成することを示していることに注意してください。

index.js

index.js次に、他のコンポーネントファイルをエクスポートできるようにする最終的なコンポーネントファイルを作成します。次のコードが含まれています。

export { default as Loader } from './Loader';
export { default as Navbar } from './Navbar';
export { default as Services } from './Services';
export { default as Transactions } from './Transactions';
export { default as Footer } from './Footer';
export { default as Welcome } from './Welcome';

Reactコンポーネントのフォーマット

次のコードスニペットをApp.jsxフォルダに含めます。

import {Navbar, Welcome, Footer, Loader, Services,Transactions} from './components';

divこれで、以下の結果を達成するためにフォーマットできます。

import {Navbar, Welcome, Footer, Loader, Services,Transactions} from './components';
const App = () =>{
  return (
    <div className="min-h-screen">
      <div className='gradient-bg-welcome'>
        <Navbar />
        <Welcome />
        </div>
        <Services />
        <Transactions />
        <Footer />
     </div>
   );
  }
export default App;

を実行するnpm run devと、上記と同じ画像が表示されます。次に、以下のコードスニペットをindex.cssファイルに追加して、スタイルを追加します。

@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap");
* html {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  margin: 0;
  font-family: "Open Sans", sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.gradient-bg-welcome {
  background-color:#0f0e13;
  background-image: 
    radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%), 
    radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%);
}
.gradient-bg-services {
  background-color:#0f0e13;
  background-image: 
    radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 100%, hsla(225,39%,25%,1) 0, transparent 50%);
}
.gradient-bg-transactions {
  background-color: #0f0e13;
  background-image: 
    radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 50%), 
    radial-gradient(at 50% 0%, hsla(225,39%,25%,1) 0, transparent 50%);
}
.gradient-bg-footer {
  background-color: #0f0e13;
  background-image: 
    radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 53%), 
    radial-gradient(at 50% 150%, hsla(339,49%,30%,1) 0, transparent 50%);
}
.blue-glassmorphism {
  background: rgb(39, 51, 89, 0.4);
  border-radius: 16px;
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  border: 1px solid rgba(0, 0, 0, 0.3);
}
/* white glassmorphism */
.white-glassmorphism {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 16px;
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  border: 1px solid rgba(255, 255, 255, 0.3);
}
.eth-card {
  background-color:#a099ff;
  background-image: 
    radial-gradient(at 83% 67%, rgb(152, 231, 156) 0, transparent 58%), 
    radial-gradient(at 67% 20%, hsla(357,94%,71%,1) 0, transparent 59%), 
    radial-gradient(at 88% 35%, hsla(222,81%,65%,1) 0, transparent 50%), 
    radial-gradient(at 31% 91%, hsla(9,61%,61%,1) 0, transparent 52%), 
    radial-gradient(at 27% 71%, hsla(336,91%,65%,1) 0, transparent 49%), 
    radial-gradient(at 74% 89%, hsla(30,98%,65%,1) 0, transparent 51%), 
    radial-gradient(at 53% 75%, hsla(174,94%,68%,1) 0, transparent 45%);
}
.text-gradient {
  background-color: #fff;
  background-image: radial-gradient(at 4% 36%, hsla(0,0%,100%,1) 0, transparent 53%), radial-gradient(at 100% 60%, rgb(0, 0, 0) 0, transparent 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
@tailwind base;
@tailwind components;
@tailwind utilities;

Navbar上記の値を追加すると、次の画像のようにセクションにカラーグラデーションが表示されます。

npm run dev

image folder次に、の中に配置される新しいにスマートコントラクトのロゴを含めますclient folder。以下のコードスニペットのように、この画像パスをNavbarファイルにインポートし、他のインポートとフォーマットをファイルに含めることで、この画像パスを含めることができます。Nav.jsx

import { HiMenuAlt4 } from 'reacts-icons/hi';
import { AiOutlineClose } from 'react-icons/ai';

import logo from '../../images/logo.png'

ターミナルで以下のコマンドを実行して、Reactアプリケーションが使用するすべての必要な依存関係をインストールしましょう。

npm install react-icons ethers

ethersブロックチェーンとスマートコントラクトを操作できます。

次に、ファイル内にあるロゴ画像を編集するために、ソースをとサイズでNavbar.jsx新しいnav classとを作成します。以下のコードスニペットのように、値を含む順序なしリストを追加します。img{logo}w-40<ul></ul>className

 <nav className='w-full flex md: justify-center justify-between items-center p-4'>
            <div className='md: flex-[0.5] flex-initial justify-center items-center'>
                <img src= {logo} alt="logo" className='w-40 cursor-pointer'/>
            </div>
            <ul className='text-white md:flex hidden list-none 
            flex-row justify-betwen items-center flex-initial'>
            </ul>
        </nav>

次に、新しい機能コンポーネントを作成し、次のNavbarItemようないくつかの小道具を設定しtitle ますclassProps

const NavbarItems = ({title, classProps }) =>{
    return (
        <li className={`mx-4 cursor-pointer ${classProps}`}>
            {title}
        </li>
    );
}

NavbarItemこれで、関数内で再利用可能なコンポーネントとしてを呼び出しNavbar、新しい動的配列ブロックを作成できます。

{["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/> )}

関数内Navbarには、次のコードがあります。

ul className='text-white md:flex hiddent list-none flex-row justify-betwen items-center flex-initial'>
{["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/>))}

次に、次のコードスニペットを使用してアプリケーションのログインボタンを作成します。

<li className='bg-[#2952e3] py-2 px-7 mx-4 rounded-full cursor-pointer hover:bg-[#2546bd]' >
Login
</li>

レスポンシブデザインの確保

NavbarモバイルデバイスとWebデバイスの両方でユーザーのディスプレイが同じになるように、レスポンシブデザインを実現したいと考えています。これを実現するために、Reactstateを導入します。これはtoggleMenu, setToggleMenu、モバイルNavbarが現在開いているときに特定のアクションを実行します。

const Navbar = () => {
    const [toggleMenu, setToggleMenu] = useState(false);
    return (
        <nav className='w-full flex md: justify-center justify-between items-center p-4'>
            <div className='md: flex-[0.5] flex-initial justify-center items-center'>
                <img src= {logo} alt="logo" className='w-40 cursor-pointer'/>
            </div>
            <ul className='text-white md:flex hiddent list-none flex-row justify-betwen items-center flex-initial'>
                  {["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item}/>))}

                 <li className='bg-[#2952e3] py-2 px-7 mx-4 rounded-full cursor-pointer hover:bg-[#2546bd]' >
                     Login
                 </li>
            </ul>
            <div className="flex relative">
                {toggleMenu
                ? <AiOutlineClose fontSize={28} className="text-white md:hidden cursor-pointer" onClick={()=>setToggleMenu(false)} /> 
                : <HiMenuAlt4 fontSize={28} className="text-white md:hidden cursor-pointer" onClick={()=>setToggleMenu(true)} />
                }
                {toggleMenu && (
                    <ul>
                        <li className='text-xl w-full my-2'>
                            <AiOutlineClose onClick={()=> setToggleMenu(false)} />
                        </li>
                        {["Market", "Exchange", "Tutorials", "Wallet"].map((item, index)=>(<NavbarItem key={item + index} title={item} classProps ="my-2 text-lg" />))}
                    </ul>
                )}
            </div>
        </nav>
    );
}
export default Navbar;

ブラウザに移動し、 [検査]を右クリックして、モバイルビューに移動します。以下と同じ画像が必要です。

上の画像から、デスクトップビューとモバイルビューの両方を表示できます。次に、コンポーネントに取り組みwelcome.jsx、いくつかの新しいものdivclassNames:を含めましょう。

 <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on crypto our wallet
                    </p>

コンポーネントには、以下のwelcome.jsxコードが含まれています。

import { AiFillAlipayCircle } from "react-icons/ai";
import { SiEthereum } from "react-icons/si";
import { BsInfoCircle }  from "react-icons/bs";
import { Loader } from './';
const commonStyles = () => 'min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white';
const Welcome = () => {

    const connectWallet = () => {
    }
    return (
        <div className="flex w-full justify-center items-center">
            <div className="flex md:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">
                <div className="flex flex-1 justify-start flex-col md:mr-10">
                    <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on crypto our wallet
                    </p>
                    <button type="button" onClick={connectWallet} className="flex flex-row justify-center items-center my-5 bg-[#2952e3] p-3 rounded-full cursor-pointer">
                        <p className= "text-white text-base font-semibold">
                        Connect Wallet
                        </p> 
                    </button>
                      <div className="grid sm:grid-cols-3 grid-cols-2 w-full mt-10">
                        <div className={`rounded-tl-2xl ${commonStyles} text-white`}>
                           Reliability
                        </div>
                       <div className={`rounded-th-2xl ${commonStyles} text-white`}>
                           Security
                        </div>
                       <div className={`rounded-tr-2xl ${commonStyles} text-white`}>
                           Ethereum
                       </div>
                       <div className={`rounded-bl-2xl ${commonStyles} text-white`}>
                           Web 3.0
                        </div>
                       <div className={`rounded-bh-2xl ${commonStyles} text-white`}>
                           Low fees
                        </div>
                       <div className={`rounded-br-2xl ${commonStyles} text-white`}>
                           Blockchain
                        </div>
                     </div>
                </div>
                <div className="flex flex-col flex-1 items-center justify-start w-full md:mt-0 mt-10">
                    <div className="p-3 justify items-start flex-col rounded-xl h-40 sm:w-72 w-full my-5 eth-card white-glassmorphism">
                        <div className="flex justify-between">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}
export default Welcome;

上記のコードベースは、以下の画像になります。私たちはいくつかdivの余分なものを含めて、それらにユニークclassNamesで、properties以下の私たちのデザインに合うように与えました:

次に、Ethereum下の画像に同じデザインのカードを追加しました。 また、ユーザーからの入力を収集するのに役立つボタンformsend Nowボタンをコンポーネントに追加しました。welcome.jsx

<Input placeholder= "Address To" name = "addressTo" type="text" handleChange={()=>{}} />
                            <Input placeholder= "Amount (ETH)" name = "amount" type="number" handleChange={()=>{}} />
                            <Input placeholder= "Keyword (gif)" name = "keyword" type="text" handleChange={()=>{}} />
                            <Input placeholder= "Enter Message" name = "message" type="text" handleChange={()=>{}} />

完全なwelcome.jsx コンポーネントのコードベースと結果を以下に示します。

ディスプレイの改善

より良い表示を実現するためにに変更することで、コードにいくつかの変更を加えmdます。mfこれらの変更は、以下のコードスニペットのクラスに実装されています。

mf:flex-row

<div className="flex mf:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">

mf:mr-1

- <div className="flex flex-1 justify-start flex-col mf:mr-10">

mf:mt-0 mt-10">

<div className="flex flex-col flex-1 items-center justify-start w-full mf:mt-0 mt-10">

tailwind.cssそれでは、ファイルのコードベースを次のコードベースに置き換えて、ファイルにいくつかの変更を加えましょうtailwind.config.js

 module.exports = {
  purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"],
  mode: "jit",
  darkMode: false, // or 'media' or 'class'
  theme: {
    fontFamily: {
      display: ["Open Sans", "sans-serif"],
      body: ["Open Sans", "sans-serif"],
    },
    extend: {
      screens: {
        mf: "990px",
      },
      keyframes: {
        "slide-in": {
          "0%": {
            "-webkit-transform": "translateX(120%)",
            transform: "translateX(120%)",
          },
          "100%": {
            "-webkit-transform": "translateX(0%)",
            transform: "translateX(0%)",
          },
        },
      },
      animation: {
        "slide-in": "slide-in 0.5s ease-out",
      },
    },
  },
  variants: {
    extend: {},
  },
  plugins: [require("/Users/peter/Dropbox/Mac/Desktop/web3.0/client/tailwind.config.js")],
};

上記のコードスニペットを使用する場合は、自分がいるpluginsローカルマシンで必要なパスに変更してくださいtailwind.config.js

plugins: [require("/Users/peter/Dropbox/Mac/Desktop/web3.0/client/tailwind.config.js")]

これで、フロントエンドの設計とReactアプリケーションが正常に完了しました。それでは、スマートコントラクトの構築を始めましょう。

Reactアプリケーションをブロックチェーンに接続する

smartContractフォルダ内のターミナルで以下のコードスニペットを実行して、依存関係をインストールします。

cd smartContract
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers

スマートコントラクトの基本構造を作成するために、専門家向けのイーサリアム開発環境であるHardhatを使用します。また、Solidityを実行し、展開前にスマートコントラクトを1回テストすることもできます。インストールが正常に完了すると、次のようなプロンプトが表示されます。

以下のコマンドを実行します。

npx hardhat

エンターボタンをクリックして基本的なサンプルプロジェクトを作成し、プロンプトが表示さ.gitignoreれたらクリックして追加します。y

contractを含むフォルダとフォルダGreeter.solがあることがわかりtestます。すべてが正常に機能していることを確認するには、次のコマンドを渡します。

npx hardhat test

次に、VS CodeエディターからSolidity拡張機能を検索し、エディターにインストールして、構文とオートコンプリート機能を支援します。

Solidityを使用してEthereumネットワークでスマートコントラクトを作成する

Greeter.solHardhatによってデフォルトで作成されたコントラクトを削除します。その後、新しいファイルを作成して名前を変更することで、独自のコントラクトを作成できますTransactions.sol.sol接尾辞はSolidityを表します。Solidityプログラミング言語は、Java、JavaScript、Rust、C++などのいくつかの言語を組み合わせたものです。

次に、以下のコードスニペットに従って、使用するSolidityのバージョンを選択します。licenseバージョンの上のコメントに必ず含めてください。

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

これで、を作成しcontract、ファイルのタイトルと同じ名前を付けて、クラスinteger内で変数を宣言できます。Transactionこの変数を使用してトランザクションを保持し、この変数に名前を付けますtransactionCounter

eventと呼ばれるを作成しますTransfer。このイベントは、、、、などのTransferパラメータを受け入れる関数のようなものです。完了する各転送には、次のプロパティが必要です。address fromaddress receiveramounttimestamp

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Transactions {
    uint256 transactionCounter;
    event Transfer (address from, address receiver, uint amount, string message, uint256 timestamp, string keyword);
    struct TransferSystem{
        address sender;
        address receiver;
        uint amount;
        string message;
        uint256 timestamp;
        string keyword;
    }
}

トランザクションを保存するために、タイプが。のトランザクションの配列を定義できますTransferSystemaddToBlockchainまた、、、、など、実行されるアクションを説明する命名規則を使用していくつかの関数を定義しgetAllTransactionsますgetTransactionCount

  TransferSystem [] transactions;

    function addToBlockchain(address payable receiver, uint amount, string memory message, string memory keyword) public{

    }
    function getAllTransactions() public view returns (TransferSystem[] memory){
    }
    function getTransactionCount() public view returns (uint256){
    }

このaddToBlockchain関数では、を1つインクリメントし、transactionCountパラメーターをプッシュしてから出力します。

function addToBlockchain(address payable receiver, uint amount, string memory message, string memory keyword) public{
        transactionCount +=1;
        transactions.push(TransferSystem(msg.sender, receiver, amount, message, block.timestamp, keyword));
        emit Transfer(msg.sender, receiver, amount, message, block.timestamp, keyword);
    }

このgetAllTransactions関数では、次を返しますtransactions

function getAllTransactions() public view returns (TransferSystem[] memory){
        return transactions;
    }

このgetTransactionsCount関数では、次を返しますtransactionCount

function getTransactionCount() public view returns (uint256){
        return transactionCount;
    }

これで、EthereumSolidityスマートコントラクトが完成しました。

Web3アプリケーションのデプロイ

スマートコントラクトをデプロイするにscriptは、VS Codeエディターに移動しsample-script.js、をクリックして名前を変更しdeploy.jsます。mainトランザクションのデプロイに役立つ関数を作成して、このファイルを編集します。また、デフォルトのGreeter定数をTransaction次のように変更します。

const main = async () => {
  const Transactions = await ethers.getContractFactory("Transactions");
  const transactions = await Transactions.deploy();
  await transactions.deployed();
  console.log("Transactions deployed to: ", transactions.address);
}
const runMain = async () => {
  try {
    await main();
    process.exit(0);
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
}
runMain ();

上記のコードスニペットは、トランザクションをブロックチェーンウォレットにデプロイするのに役立ちます。しかし、そうするためには、すでにイーサリアムまたはガスが必要です。ガスとは、取引を行うために必要なエーテルの一部を指します。Ropsten Testnet Faucetにアクセスして、テストイーサリアムを入手できます。ウォレットアドレスも提供する必要があります。このために、ブラウザでMetamask拡張機能を設定する必要があります。

これで、 show test networkのトグルを変更して、EthereumMainnetでテストネットワークを有効にできます。

右上隅で、EthereumMainnetをRopstenTestNetworkに変更できます。

これで、アカウント1からアカウントアドレスをコピーして、RopstenTestFaucetに貼り付けることができます。

ブロックチェーンをデプロイするには、Alchemyに移動します。ここでのネットワークの選択はRopstenになることに注意してください。これにより、実際のイーサリアムガス料金を支払うことができなくなります。

Alchemyでアカウントを正常に作成したら、右上隅にある[アプリの作成]をクリックして、希望する詳細を入力します。次に、ビューキーをクリックして、HTTPキーをコピーします。

これで、プラグインとしてhardhat.config.js使用してスマートコントラクトをテストするために戻ることができます。以下のコードのようにhardhat-waffles編集する必要があります。hardhat.config.js

require('@nomiclabs/hardhat-waffle');
module.exports = {
  solidity : '0.8.0',
  networks : {
    ropsten:{
      url: `https://eth-ropsten.alchemyapi.io/v2/SFRRwFrEK3nQkYAis0Z0dBLjcWEHtztJ`,
      accounts: ['085164c615a0edb827a8ee5c1759b7c704bc519130841121ad07b21aff359929']
    } 
  }
}

このhardhat.config.jsフォルダーでは、上記で生成された秘密鍵をアカウントに割り当てましたが、URLはAlchemyからのHTTPです。アプリケーションをデプロイするには、に移動してterminal次のコマンドを入力します。

npx hardhat run scripts/deploy.js --network ropsten

次の画像のように、生成された住所番号を取得します。

次に、に移動し、client folderを右クリックしてsrc、という名前の新しいフォルダを作成しますutils。フォルダ内にutil、という新しいファイルを作成し、constant.js以下のコードスニペットを使用して生成されたアドレスを入力できます。

export const contractAddress= `0x02207Ac5b9ffc1d8BFc242ad3BAB1A44Ebc7D9bb`;

→→→→にsmartContract進みます。artifact_ アプリケーションバイナリインターフェイスを意味するABIは、イーサリアムシステムのスマートコントラクトと対話するための標準的な方法です。Transactions.solTransactions.jsonabi

次に、すべてをコピーしてから、フォルダTransactions.json内に作成する新しいファイルに貼り付けます。utilsこの新しいファイルに名前を付けることができますTransactions.jsonconstants.js以下のコードスニペットを使用して、これをフォルダにインポートしましょう。

import abi from `./Transactions.json`;
export const contractABI = abi.abi;
export const contractAddress = `0x02207Ac5b9ffc1d8BFc242ad3BAB1A44Ebc7D9bb`;

次に、srcという名前のフォルダーとcontext、という名前のファイルを作成します。これにより、アプリケーション全体でReactContextAPITransactionContext.jsxを使用できるようになります。

import React, {useEffects, useState} from 'react';
import { ethers } from 'ethers';
import { contractABI, ContractABI, contractAddress } from '../util/constants';
export const TransactionContext = React.createContext();
const { ethereum } = window;
const getEthereumContract = () => {
    const provider = new ethers.provider.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);

    console.log({
        provider,
        signer,
        transactionContract
    });
}
export const transactionProvider = ( children ) => {
    return (
        <TransactionContext.Provider value={{value: 'test'}}>
            {children}
        </TransactionContext.Provider>
    );
}

また、以下のコードスニペットのようにファイルにインポートTransactionContextします。main.jsx

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import TransactionContext from './context/TransactionContext'
ReactDOM.render(
  <TransactionProvider>

  <React.StrictMode>
    <App />
  </React.StrictMode>
  </TransactionProvider>,
  document.getElementById('root')
)

TransactionContext.jsx以下で共有するのコードスニペットにいくつかの変更を加えました。

import React, {useEffect, useState} from 'react';
import { ethers } from 'ethers';
import { contractABI, contractAddress } from '../util/constants';
export const TransactionContext = React.createContext();
const { ethereum } = window;
const getEthereumContract = () => {
    const provider = new ethers.provider.Web3Provider(ethereum);
    const signer = provider.getSigner();
    const transactionContract = new ethers.Contract(contractAddress, contractABI, signer);

   return transactionContract;
}
export const TransactionProvider = ({children}) => {
     const [currentAccount, setCurrentAccount] = useState('');
     const [formData, setFormData] = useState({addressTo: '', amountTo: '', keyword: '', message: ''});
     const [isLoading, setIsLoading] = useState(false);
     const [transactionCount, setTransaction] = useState(localStorage.getItem('transactionCount'));
     const handleChange = (e, name) => {
         setFormData((prevState) => ({ ...prevState, [name]: e.target.value }));
     }
      const checkIfWalletIsConnected = async () => {

    try{
        if (!ethereum) return alert ("Please install metamask!");
        const accounts = await ethereum.request({ method: 'eth_accounts'});
        if(accounts.length){
            setCurrentAccount(accounts[0]);
        }
        else{
            console.log("No accout found!");
        }
        console.log(accounts);
      } catch(error) {

        throw new Error("No ethereum object...");
    }
  }    
      const connectWallet = async () => {
          try {
            if (!ethereum) return alert ("Please install metamask!");
            const accounts = await ethereum.request({ method: 'eth_requestAccounts'});
            setCurrentAccount(accounts[0]);
          } catch (error) {
              console.log(error);
              throw new Error("No ethereum object...");
          }
      }
      const sendTransaction = async () => {
          try {
            if (!ethereum) return alert ("Please install metamask!");
            const {addressTo, amount, keyword, message} = formData;
            const transactionContract = getEthereumContract();
            const parsedAmount = ethers.utils.parsedEther(amount);
            await ethereum.request({ 
                method: 'eth_sendTransactions',
                params: [{
                from: currentAccount,
                to: addressTo, 
                gas: '0x5208',
                vaue: parsedAmount._hex,    
                }]
            });
           const transactionHash = await transactionContract.addToBlockchain(addressTo,parsedAmount,message,keyword);

           setIsLoading(true);
           console.log(`Loading - ${transactionHash.hash}`);
           await transactionHash.wait();
           setIsLoading(false);
           console.log(`Success - ${transactionHash.hash}`);
           const transactionCount = await transactionContract.getTransactionCount();
           setTransactionCount(transactionCount.toNumber());
          } catch (error) {
            console.log(error);
            throw new Error("No ethereum object...");
          }
      }
     useEffect(()=> {
        checkIfWalletIsConnected();
     },[]);
    return (
        <TransactionContext.Provider value={{connectWallet, currentAccount,formData,setFormData,handleChange, sendTransaction}}>
            {children}
        </TransactionContext.Provider>
    );
   }

 

Welcome.jsx以下のコードは、コンポーネントに加えられたすべての追加の変更を示しています。

import { AiFillAlipayCircle } from "react-icons/ai";
import { SiEthereum } from "react-icons/si";
import { BsInfoCircle }  from "react-icons/bs";
import { TransactionContext } from "../context/TransactionContext";
import React, { useContext } from 'react';
import { Loader } from './';
const Input = ({placeholder, name, type, value, handleChange}) => (
    <input
    placeholder={placeholder}
    type={type}
    step= "0.0001"
    value={value}
    onChange={(e)=>handleChange(e,name)}
    className= "my-2 w-full rounded-sm p-2 outline-none bg-transparent text-white border-none text-sm white-glassmorphism"
    />
);
const commonStyles = () => 'min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white';
const Welcome = () => {
    const { connectWallet, currentAccount, formData, sendTransaction, handleChange } = useContext(TransactionContext);
    const handleSubmit = (e) => {
        const {addressTo, amount, keyword, message} = formData;

        e.preventDefault();
        if(!addressTo || !amount ||  !keyword || !message) return;
        sendTransaction();
    }
    return (
        <div className="flex w-full justify-center items-center">
            <div className="flex mf:flex-row flex-col items-start justify-between md:p-20 py-12 px-4">
                <div className="flex flex-1 justify-start flex-col mf:mr-10">
                    <h1 className="text-3xl sm:text-5xl text-white text-gradient py-1"> 
                        Blockchain and Crypto Transactions<br /> across the world
                    </h1>
                    <p className="text-left mt-5 text-white font-light md:w-9/12 w-11/12 text-base">
                        Explore the Crypto world. Buy and sell cryptocurrencies easily on our crypto wallet
                    </p>
                    {!currentAccount && (<button type="button" onClick={connectWallet} className="flex flex-row justify-center items-center my-5 bg-[#2952e3] p-3 rounded-full cursor-pointer">

                        <p className= "text-white text-base font-semibold">Connect Wallet</p> 
                    </button>)}
                      <div className="grid sm:grid-cols-3 grid-cols-2 w-full mt-10">
                        <div className={`rounded-tl-2xl ${commonStyles} text-white`}>
                           Reliability
                        </div>
                       <div className={`rounded-th-2xl ${commonStyles} text-white`}>
                           Security
                        </div>
                       <div className={`rounded-tr-2xl ${commonStyles} text-white`}>
                           Ethereum
                       </div>
                       <div className={`rounded-bl-2xl ${commonStyles} text-white`}>
                           Web 3.0
                        </div>
                       <div className={`rounded-bh-2xl ${commonStyles} text-white`}>
                           Low fees
                        </div>
                       <div className={`rounded-br-2xl ${commonStyles} text-white`}>
                           Blockchain
                        </div>
                     </div>
                </div>
                <div className="flex flex-col flex-1 items-center justify-start w-full mf:mt-0 mt-10">
                    <div className="p-3 justify-end items-start flex-col rounded-xl h-40 sm:w-72 w-full my-5 eth-card white-glassmorphism">
                        <div className="flex justify-between flex-col w-full h-full">
                            <div className="flex justify-between items-start">
                                <div className="w-10 h-10 rounded-full border-2 border-white flex justify-center items-center">
                                    <SiEthereum fontSize={21} color="#fff" />
                                </div>
                                <BsInfoCircle fontSize={17} color="#fff"/>
                                </div>
                                <div>
                                <p className="text-white font-light text-sm">
                                 Address (0Xapdpqdf.......fdsb)
                                </p>
                                <p className="text-white font-light text-white font-semibold text-lg mt-1">
                                    ETHEREUM
                                </p>
                             </div>
                            </div>
                        </div>
                        <div className="p-5 sm:w-96 flex-full flex flex-col justify-start items-center blue-glassmorphism">

                            <Input placeholder= "Address To" name = "addressTo" type="text" handleChange={handleChange} />
                            <Input placeholder= "Amount (ETH)" name = "amount" type="number" handleChange={handleChange} />
                            <Input placeholder= "Keyword (gif)" name = "keyword" type="text" handleChange={handleChange} />
                            <Input placeholder= "Enter Message" name = "message" type="text" handleChange={handleChange} />
                            <div className="h-[1px] w-full bg-gray-400 my-2" />
                            {false ?(
                                <Loader />
                            ): (
                                <button
                                type="button"
                                onClick={handleSubmit}
                                className="text-white w-full mt-2 border-[1px] p-2 border-[#3d4f7c] rounded-full cursor-pointer">
                                    Send Now
                                </button>
                            )}
                        </div>
                </div>
            </div>
        </div>
    );
}
export default Welcome;

それでは、先に進んでアプリケーションをテストしましょう。

Web3アプリケーションのテスト

アプリケーションをテストするために、Metamaskを開いて新しいアカウントを作成し、別のアドレスを生成して送金することができます。

2つ目のアカウントが正常に作成されたら、アドレスをコピーaddressToしてブラウザページに貼り付け、送信するイーサリアムの量を選択し、キーワードまたはメッセージを渡して、[今すぐ送信 ]ボタンをクリックします。

アプリケーションを再起動した後、ウォレットに接続ボタンをクリックして、Metamaskに再度接続する必要があることに注意してください。トランザクションを完了する前に、次のことを行ってください。

イーサを送る

イーサを受け取る

完成したプロジェクトをYouTubeでチェックすることもできます。

結論

この記事では、Web3アプリケーションを最初から作成することに成功しました。Solidityプログラミング言語を使用してアプリケーションを構築するために深く掘り下げる前に、Web3テクノロジーの紹介から始めました。次に、アプリケーションをテストし、ブロックチェーントランザクションを実行しました。

この記事全体を通して、SolidityとJavaScriptがスマートコントラクトの開発において果たす大きな役割を観察してきました。Reactを使用して、、などのいくつかのコンポーネントを使用してスマートコントラクトのフロントエンドを開発し、Solidityを使用してLoaderスマートwelcomeコントラクトを構築しました。この記事で概説されている手順に従って、Ethereumネットワーク上で最初のスマートコントラクトを構築できます。

この記事がお役に立てば幸いです。Web3をどのように改善できるかについてのご意見をお聞かせください。質問や懸念がある場合は、コメントを残してください。あなたのプロジェクトを楽しみにしています。ハッピーコーディング!

ソース:https ://blog.logrocket.com/solidity-javascript-web3-blockchain-applications/ 

 #javascript #solidity #web3 #blockchain #applications