【前言】
终於到了验证的最後一步啦,感觉时间过得很快,一眨眼就到了这里,网站也变得非常完整。感谢大家的陪伴,让我们继续迈向终点吧!
【定义 Ownership】
接续着上次的内容,这边我们可以藉由 bignumber.js 的函数 toString()
来转成字串,并藉此定义 OwnerShip
。
console.log(balance.toNumber());
if(balance.toString() === "1"){
setOwnerShip(true);
}
console.log(OwnerShip);
};
然後我们就可以传出 OwnerOf()
这个函数,届时就可以利用 OwnerOf().OwnerShip
来得到到底这个 Token 是不是属於当前登入者的!
export function OwnerOf(account, id) {
const [a, setA] = useState({
tokenAddress: "我们智能合约的地址",
tokenId: id, // Token ID
schemaName: 'ERC721'
});
const [accountAddress, setAccountAddress] = useState(account)
const [OwnerShip, setOwnerShip] = useState(false)
useEffect(() => {
const fetchData = async () => {
const balance = await seaport.getAssetBalance({
accountAddress: accountAddress,
asset: {
tokenAddress: a.tokenAddress,
tokenId: a.tokenId,
schemaName: a.schemaName
},
})
console.log(balance.toString());
if(balance.toString() === "1"){
setOwnerShip(true);
}
};
fetchData();
}, []);
return (
{ OwnerShip }
);
}
【资料传递】
大家还记得我们那时候取得使用者登入帐号的部分吗!现在我们要把资料传出来。
首先先在登入区取得当前登入者的帐户资料,也可以透过导入 web3.js
套件之後利用 web3.eth.coinbase
的方式取得!之後我们就不需要登入者再输入一次以太坊地址了,我们使用自动填入的功能。
此外我们在导至 VIP 页面的时候也要顺便把使用者帐户利用 react-router-dom
中 Link
可以附带 state
的功能传出去,当然也可以到 VIP 页面的时候用上述方法重新抓一次地址及使用者欲登入的 id
,或从後端直接调资料,不过我就想试试看这个方法。
export function LoginForm(props) {
const [ accounts, setAccounts ] = useState([]);
const [ inputID, setInputID ] = useState('');
...
useEffect(() => {
window.ethereum
.request({ method: 'eth_requestAccounts' })
.then((newAccounts) => setAccounts(newAccounts));
...
}, []);
return (
<BoxContainer>
...
<SubmitButton type="submit" to={{
pathname: "/VIP",
state: { ac: accounts,
id: inputID}
}}>Enter</SubmitButton>
...
</BoxContainer>
);
}
这边有个小细节是因为我们只会发行一万只的角色,如果这时候使用者随便填入一个智能合约中不存在的 id
会导致 compiler error
,所以特别在 button tag
做 style
利用 pointerEvents
的限制就可以解决问题!
export function LoginForm(props) {
const [ accounts, setAccounts ] = useState([]);
const [ inputID, setInputID ] = useState('My Dino ID');
const [ go, setGo ] = useState({ pointerEvents: "none" })
...
useEffect(() => {
var i = Number(inputID);
if( 0 <= i && i <= 9999){
setGo({pointerEvents: "auto" })
}
else{
setGo({pointerEvents: "none" })
}
}, [inputID]);
return (
<BoxContainer>
<Input type="text" placeholder="My Dino ID" value={inputID} onInput={e => setInputID(e.target.value)} />
<Input type="text" placeholder="My Ethereum Address" value={ accounts } onInput={e => setAccounts(e.target.value)} />
...
<SubmitButton type="submit" style={ go } to={{
pathname: "/VIP",
state: { ac: accounts,
id: inputID}
}}>Enter</SubmitButton>
...
</BoxContainer>
);
}
pointer-events - CSS(层叠样式表) | MDN
在这边我们先 call UseLocation
出来,然後利用 state.ac
就可以得到我们从前一个地方来的 state
。
import { useLocation } from "react-router-dom";
...
export function VIP(props) {
...
const location = useLocation();
const [accounts, setAccounts] = useState(location.state.ac);
const id = location.state.id;
const OS = OwnerOf(accounts[0], id).OwnerShip;
...
return (
<Wrapper>
...
</Wrapper>
);
}
这边可以确实接收到资料,其中依序 print 出的是: 0
表示 accounts
以及 Token
有 0 组契合;登入者的地址;欲查询 Ownership 的 Token ID
;Ownership
。
【验证成功 & 验证失败】
我发现 call opnesea.js 的 getAssetBalance()
会有一些延迟才会得到真正的 ownership,所以我们必须要有一个 Loading Message。这边就不多加叙述了,因为前面做过很多次方法都差不多!
如果今天是验证失败的话我们就要导回到 DINO Login 的地方,但因为 DINO Login 的使用者地址是直接抓 window.ethereum
取得的,所以就不用像上面一样使用 react-router-dom
中 Link
搭配UseLocation
的方式找到地址。
export function VIP(props) {
...
return (
<Wrapper>
{ isPending && <LoaderTEXT /> }
{ !isPending && !OS && <Link1 to="/login">Verified Failed! Click to direct back DINO Login.</Link1> }
{/* failed */}
{ !isPending && OS && isVering && <VerifiedSuc>Verified Successfully!</VerifiedSuc> }
{ !isPending && OS && !isVering && <div></div> }
{/* successfully */}
</Wrapper>
);
}
验证失败的话会回传一个 Link 可以让使用者回到 DINO Login。成功的话就会进到 VIP 专属的互动区!
【小结】
到这边网页的部分就正式结束啦!真的好累天啊,学到了超多新东西,也遇到了无数的困难,总归还是还行地完成了这个不小的企划。有很多心得想要讲的只是那些话就留给结语吧!接下来几天我会分享除了我专责的网页任务内容外,其他在上链工程的部分!
【参考资料】
opensea-js
bignumber
React Router: Declarative Routing for React
React CSS
<<: Day 30 整合宝石:【Lab】建构三层式云端架构 (EC2+VPC+S3+RDS+IAM) (下)
本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtu...
今天大概会聊到的范围 AnnotatedString Text 在 Compose 中显示文字时,...
#16. Quiz App 所谓Quiz App就是提供给用户答题的小应用,包含数个选择题,选完一个...
我们在Day 7的时候曾经介绍过基於达尔文物竞天择适者生存的演化式计算,那麽今天开始我们就来详细的介...
C-新增 R-查询 U-更改 D-删除 流程: 建置 设定 show 4.一定会有key:value...