1649826986
技術愛好家またはWeb開発者であるということは、最新の技術とトレンドを常に把握していることを意味します。多くのソフトウェア開発者は、絶え間ない自己開発と改善の方法として個人的なプロジェクトに取り組んでいるため、ブロックチェーン開発、イーサリアム、スマートコントラクト、DApp、SolidityプログラミングなどのWeb3プログラミングの話題の言葉にすでに精通しているかもしれません。
この記事では、これらの用語を深く掘り下げ、ブロックチェーン愛好家や開発者が個人のポートフォリオを強化するために使用できるライブWeb3プロジェクトを構築してホストすることでカバーした内容を固めます。このチュートリアルに従うには、次のものが必要です。
GitHubのクローンを作成して、このチュートリアルで使用されている完全なコードを表示することもできます。始めましょう!
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プロジェクトを構築しましょう。
このプロジェクトを開始するには、ホスティングサイトを選択し、ドメイン名を購入することをお勧めします。個人的なプロジェクトにお金をかけたくない場合は、Hostinger、Heroku、Netlifyなどのホスティングサイトを試してプロジェクトを展開することができます。
デスクトップにフォルダを作成し、のような名前を付けてweb3.0 project
、コードエディタでこのフォルダを開きます。これで、コードエディターで新しいフォルダーを作成し、client
Reactアプリケーションを配置する場所に名前を付けることができます。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コンポーネントの構築を開始できます。
イーサリアムネットワーク上でスマートコントラクトを構築することに焦点を当てます。これを行うには、以下のコマンドを使用して、ローカルマシンの新しいターミナルのフォルダに移動しますcd
。smartcontract
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
は同義語ですが、jsx
Reactコードを作成することを示していることに注意してください。
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';
次のコードスニペットを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
、いくつかの新しいものdiv
とclassNames
:を含めましょう。
<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
下の画像に同じデザインのカードを追加しました。 また、ユーザーからの入力を収集するのに役立つボタンform
とsend 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アプリケーションが正常に完了しました。それでは、スマートコントラクトの構築を始めましょう。
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拡張機能を検索し、エディターにインストールして、構文とオートコンプリート機能を支援します。
Greeter.sol
Hardhatによってデフォルトで作成されたコントラクトを削除します。その後、新しいファイルを作成して名前を変更することで、独自のコントラクトを作成できます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;
}
}
トランザクションを保存するために、タイプが。のトランザクションの配列を定義できますTransferSystem
。addToBlockchain
また、、、、など、実行されるアクションを説明する命名規則を使用していくつかの関数を定義し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スマートコントラクトが完成しました。
スマートコントラクトをデプロイするに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.json
。constants.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;
それでは、先に進んでアプリケーションをテストしましょう。
アプリケーションをテストするために、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
1649826986
技術愛好家またはWeb開発者であるということは、最新の技術とトレンドを常に把握していることを意味します。多くのソフトウェア開発者は、絶え間ない自己開発と改善の方法として個人的なプロジェクトに取り組んでいるため、ブロックチェーン開発、イーサリアム、スマートコントラクト、DApp、SolidityプログラミングなどのWeb3プログラミングの話題の言葉にすでに精通しているかもしれません。
この記事では、これらの用語を深く掘り下げ、ブロックチェーン愛好家や開発者が個人のポートフォリオを強化するために使用できるライブWeb3プロジェクトを構築してホストすることでカバーした内容を固めます。このチュートリアルに従うには、次のものが必要です。
GitHubのクローンを作成して、このチュートリアルで使用されている完全なコードを表示することもできます。始めましょう!
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プロジェクトを構築しましょう。
このプロジェクトを開始するには、ホスティングサイトを選択し、ドメイン名を購入することをお勧めします。個人的なプロジェクトにお金をかけたくない場合は、Hostinger、Heroku、Netlifyなどのホスティングサイトを試してプロジェクトを展開することができます。
デスクトップにフォルダを作成し、のような名前を付けてweb3.0 project
、コードエディタでこのフォルダを開きます。これで、コードエディターで新しいフォルダーを作成し、client
Reactアプリケーションを配置する場所に名前を付けることができます。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コンポーネントの構築を開始できます。
イーサリアムネットワーク上でスマートコントラクトを構築することに焦点を当てます。これを行うには、以下のコマンドを使用して、ローカルマシンの新しいターミナルのフォルダに移動しますcd
。smartcontract
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
は同義語ですが、jsx
Reactコードを作成することを示していることに注意してください。
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';
次のコードスニペットを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
、いくつかの新しいものdiv
とclassNames
:を含めましょう。
<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
下の画像に同じデザインのカードを追加しました。 また、ユーザーからの入力を収集するのに役立つボタンform
とsend 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アプリケーションが正常に完了しました。それでは、スマートコントラクトの構築を始めましょう。
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拡張機能を検索し、エディターにインストールして、構文とオートコンプリート機能を支援します。
Greeter.sol
Hardhatによってデフォルトで作成されたコントラクトを削除します。その後、新しいファイルを作成して名前を変更することで、独自のコントラクトを作成できます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;
}
}
トランザクションを保存するために、タイプが。のトランザクションの配列を定義できますTransferSystem
。addToBlockchain
また、、、、など、実行されるアクションを説明する命名規則を使用していくつかの関数を定義し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スマートコントラクトが完成しました。
スマートコントラクトをデプロイするに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.json
。constants.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;
それでは、先に進んでアプリケーションをテストしましょう。
アプリケーションをテストするために、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/