이더 리움 DAPP 건축 : 화이트리스트 및 테스트 스토리 DAO
키 포인트
스토리 DAO는 OpenZeppelin의 자체 계약을 사용하여 소유자 만 관리 기능을 수행 할 수 있도록하여 DAPP 운영에 대한 보안 및 제어를 향상시킵니다. 스토리 DAO 계약에는 조정 가능한 수수료 및 기간 매개 변수가 있으며 승인되지 않은 변경을 방지하기 위해 보안 조치가 장착되어 소유자 만 중요한 설정을 수정할 수 있습니다.
스토리의 화이트리스트 관리는 발신자의 기여에 따라 자동 및 조건부 액세스를 허용하는 유료 기능을 통해 구현됩니다.-
스토리 DAO의 배포 프로세스는 송로 버섯으로 단순화되며 특정 마이그레이션 스크립트 및 구성으로 개발 환경에서 생산 환경으로 원활한 전환을 촉진합니다. -
이 튜토리얼 시리즈의 세 번째 부분은 이더 리움을 사용하여 DAPP를 구축하는 것을 설명합니다. 여기서 Token을 Ethereum Test Network Rinkeby에 구축하고 배포합니다. 이 섹션에서는 스토리 DAO 코드를 쓰기 시작합니다. - 계약 개요 새로운 계약을 만들어 봅시다. 스토리 데어 (STORYDAO.SOL)는 다음과 같이있다.
- 우리는 안전한 계산을 다시하기 위해 Safemath를 가져 오지만 이번에는 Zeppelin의 자체 계약을 사용하여 누군가가 스토리를 "소유"하고 특정 관리자 전용 기능을 수행 할 수 있습니다. 간단히 말해서, 우리의 스토리 데이는 계약이 어떻게 작동하는지 이해하기에 충분합니다.
-
만이 함수에 추가되면 함수의 본문이 _가 위치한 위치에 붙여지고 이전 부분이 먼저 실행됩니다. 따라서이 수정자를 사용함으로써 함수는 메시지 발신자가 계약의 소유자인지 자동으로 확인한 다음 사실이라면 평소와 같이 계속됩니다. 그렇지 않으면 충돌합니다.
테스트
참고 : 견고성 테스트는 일반적으로 저수준 계약 기반 기능, 즉 스마트 계약의 내부 구조를 테스트하는 데 사용됩니다. JS 테스트는 종종 계약이 외부에서 올바르게 상호 작용할 수 있는지 테스트하는 데 사용됩니다. 이것이 최종 사용자가 할 일입니다.
- 선언이 참인지 거짓인지 확인합니다. 이 예에서는 숫자를 배치 된 계약의 초기 값과 비교합니다. "true"가 될 때마다 Assert.equals 섹션은 "True"를 나타내는 이벤트를 발행합니다.이 사건은 Truffle이 테스트 중에 듣는 것입니다.
<,>이 시점에서, 우리는 또한 프로젝트 폴더의 루트에있는 package.json 파일을 업데이트 (또는 지금까지 필요한 종속성과 향후 필요한 것)를 업데이트해야합니다. >
<🎜 🎜> <<> 참고 : 우리는 안전한 계산을위한 SAFEMATH 기능이기 때문에 서브를 빼기 위해 서브를 사용합니다.
이더 리움 dapps 및 화이트리스트 건물에 대한
블록 체인의 스마트 계약은 불변이기 때문에 배포 후 DAPP를 업데이트하는 것은 어려울 수 있습니다. 그러나 데이터 및 논리를 다른 계약으로 분리하거나 위임 된 통화를 사용하여 계약을 업그레이드하여 업그레이드 가능한 계약을 설계 할 수 있습니다. DAPP의 설계 단계에서 업그레이드 및 변경 계획은 매우 중요합니다. pragma solidity ^0.4.24;
import "../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../node_modules/openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract StoryDao is Ownable {
using SafeMath for uint256;
mapping(address => bool) whitelist;
uint256 public whitelistedNumber = 0;
mapping(address => bool) blacklist;
event Whitelisted(address addr, bool status);
event Blacklisted(address addr, bool status);
uint256 public daofee = 100; // 百分之几,即 100 为 1%
uint256 public whitelistfee = 10000000000000000; // 以 Wei 为单位,这是 0.01 以太币
event SubmissionCommissionChanged(uint256 newFee);
event WhitelistFeeChanged(uint256 newFee);
uint256 public durationDays = 21; // 故事章节持续时间(天)
uint256 public durationSubmissions = 1000; // 故事章节持续时间(条目)
function changedaofee(uint256 _fee) onlyOwner external {
require(_fee <= 1000); // 限制最大费用为 10%
daofee = _fee;
emit SubmissionCommissionChanged(_fee);
}
function changewhitelistfee(uint256 _fee) onlyOwner external {
require(_fee > 0); // 确保费用大于 0
whitelistfee = _fee;
emit WhitelistFeeChanged(_fee);
}
function changeDurationDays(uint256 _days) onlyOwner external {
require(_days >= 1);
durationDays = _days;
}
function changeDurationSubmissions(uint256 _subs) onlyOwner external {
require(_subs > 99);
durationSubmissions = _subs;
}
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
export default async promise => {
try {
await promise;
} catch (error) {
const invalidOpcode = error.message.search('invalid opcode') >= 0;
const outOfGas = error.message.search('out of gas') >= 0;
const revert = error.message.search('revert') >= 0;
assert(
invalidOpcode || outOfGas || revert,
'Expected throw, got \'' + error + '\' instead',
);
return;
}
assert.fail('Expected throw not received');
};
pragma solidity ^0.4.24;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/StoryDao.sol";
contract TestStoryDao {
function testDeploymentIsFine() public {
StoryDao sd = StoryDao(DeployedAddresses.StoryDao());
uint256 daofee = 100; // 百分之几,即 100 为 1%
uint256 whitelistfee = 10000000000000000; // 以 Wei 为单位,这是 0.01 以太币
uint256 durationDays = 21; // 故事章节持续时间(天)
uint256 durationSubmissions = 1000; // 故事章节持续时间(条目)
Assert.equal(sd.daofee(), daofee, "初始 DAO 费用应为 100");
Assert.equal(sd.whitelistfee(), whitelistfee, "初始白名单费用应为 0.01 以太币");
Assert.equal(sd.durationDays(), durationDays, "初始天数持续时间应设置为 3 周");
Assert.equal(sd.durationSubmissions(), durationSubmissions, "初始提交持续时间应设置为 1000 个条目");
}
}
import expectThrow from './helpers/expectThrow';
const StoryDao = artifacts.require("StoryDao");
contract('StoryDao Test', async (accounts) => {
it("should make sure environment is OK by checking that the first 3 accounts have over 20 eth", async () =>{
assert.equal(web3.eth.getBalance(accounts[0]).toNumber() > 2e+19, true, "Account 0 has more than 20 eth");
assert.equal(web3.eth.getBalance(accounts[1]).toNumber() > 2e+19, true, "Account 1 has more than 20 eth");
assert.equal(web3.eth.getBalance(accounts[2]).toNumber() > 2e+19, true, "Account 2 has more than 20 eth");
});
it("should make the deployer the owner", async () => {
let instance = await StoryDao.deployed();
assert.equal(await instance.owner(), accounts[0]);
});
it("should let owner change fee and duration", async () => {
let instance = await StoryDao.deployed();
let newDaoFee = 50;
let newWhitelistFee = 1e+10; // 1 ether
let newDayDuration = 42;
let newSubsDuration = 1500;
instance.changedaofee(newDaoFee, {from: accounts[0]});
instance.changewhitelistfee(newWhitelistFee, {from: accounts[0]});
instance.changeDurationDays(newDayDuration, {from: accounts[0]});
instance.changeDurationSubmissions(newSubsDuration, {from: accounts[0]});
assert.equal(await instance.daofee(), newDaoFee);
assert.equal(await instance.whitelistfee(), newWhitelistFee);
assert.equal(await instance.durationDays(), newDayDuration);
assert.equal(await instance.durationSubmissions(), newSubsDuration);
});
it("should forbid non-owners from changing fee and duration", async () => {
let instance = await StoryDao.deployed();
let newDaoFee = 50;
let newWhitelistFee = 1e+10; // 1 ether
let newDayDuration = 42;
let newSubsDuration = 1500;
await expectThrow(instance.changedaofee(newDaoFee, {from: accounts[1]}));
await expectThrow(instance.changewhitelistfee(newWhitelistFee, {from: accounts[1]}));
await expectThrow(instance.changeDurationDays(newDayDuration, {from: accounts[1]}));
await expectThrow(instance.changeDurationSubmissions(newSubsDuration, {from: accounts[1]}));
});
it("should make sure the owner can only change fees and duration to valid values", async () =>{
let instance = await StoryDao.deployed();
let invalidDaoFee = 20000;
let invalidDayDuration = 0;
let invalidSubsDuration = 98;
await expectThrow(instance.changedaofee(invalidDaoFee, {from: accounts[0]}));
await expectThrow(instance.changeDurationDays(invalidDayDuration, {from: accounts[0]}));
await expectThrow(instance.changeDurationSubmissions(invalidSubsDuration, {from: accounts[0]}));
})
});
pragma solidity ^0.4.24;
import "../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";
import "../node_modules/openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract StoryDao is Ownable {
using SafeMath for uint256;
mapping(address => bool) whitelist;
uint256 public whitelistedNumber = 0;
mapping(address => bool) blacklist;
event Whitelisted(address addr, bool status);
event Blacklisted(address addr, bool status);
uint256 public daofee = 100; // 百分之几,即 100 为 1%
uint256 public whitelistfee = 10000000000000000; // 以 Wei 为单位,这是 0.01 以太币
event SubmissionCommissionChanged(uint256 newFee);
event WhitelistFeeChanged(uint256 newFee);
uint256 public durationDays = 21; // 故事章节持续时间(天)
uint256 public durationSubmissions = 1000; // 故事章节持续时间(条目)
function changedaofee(uint256 _fee) onlyOwner external {
require(_fee <= 1000); // 限制最大费用为 10%
daofee = _fee;
emit SubmissionCommissionChanged(_fee);
}
function changewhitelistfee(uint256 _fee) onlyOwner external {
require(_fee > 0); // 确保费用大于 0
whitelistfee = _fee;
emit WhitelistFeeChanged(_fee);
}
function changeDurationDays(uint256 _days) onlyOwner external {
require(_days >= 1);
durationDays = _days;
}
function changeDurationSubmissions(uint256 _subs) onlyOwner external {
require(_subs > 99);
durationSubmissions = _subs;
}
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
DAO는 분산 된 자율 조직을 나타냅니다. 그것은 조직 구성원이 통제하고 중앙 정부의 영향을받지 않는 컴퓨터 프로그램으로 인코딩 된 규칙으로 표현되는 조직 유형입니다. DAO의 금융 거래 및 규칙은 블록 체인에 보관되어 DAPP가됩니다.
DAPP 개발은 몇 가지 과제에 직면 해 있습니다. 여기에는 이더 리움 네트워크의 확장 성 문제를 다루고, DAPP의 보안을 보장하고, 거래를위한 휘발성 가스 가격 관리 및 사용자 친화적 인 인터페이스 제공이 포함됩니다. 또한 빠르게 진화하는 블록 체인 기술 및 규정을 주시해야합니다.
위 내용은 이더 리움 DAPP 건축 : 화이트리스트 및 테스트 스토리 DAO의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

CNCF (Cloud Native Computing Foundation), Ampere Computing, Equinix Metal 및 Actuated 간의 공동 작업 인이 파일럿 프로그램은 CNCF Github 프로젝트를위한 ARM64 CI/CD를 간소화합니다. 이 이니셔티브는 보안 문제 및 성과를 다룹니다

이 튜토리얼은 AWS 서비스를 사용하여 서버리스 이미지 처리 파이프 라인을 구축함으로써 안내합니다. ECS Fargate 클러스터에 배포 된 Next.js Frontend를 만들어 API 게이트웨이, Lambda 기능, S3 버킷 및 DynamoDB와 상호 작용합니다. th

이 최고의 개발자 뉴스 레터와 함께 최신 기술 트렌드에 대해 정보를 얻으십시오! 이 선별 된 목록은 AI 애호가부터 노련한 백엔드 및 프론트 엔드 개발자에 이르기까지 모든 사람에게 무언가를 제공합니다. 즐겨 찾기를 선택하고 Rel을 검색하는 데 시간을 절약하십시오

ARM64 아키텍처의 오픈 소스 소프트웨어를위한 CI/CD 퍼즐 및 솔루션 ARM64 아키텍처에 오픈 소스 소프트웨어를 배포하려면 강력한 CI/CD 환경이 필요합니다. 그러나 ARM64의지지 수준과 기존 X86 프로세서 아키텍처 사이에는 차이가 있으며, 이는 종종 단점이 있습니다. 인프라 구성 요소 여러 아키텍처를위한 개발자는 작업 환경에 대한 특정 기대치가 있습니다. 일관성 : 플랫폼에 사용 된 도구와 방법은 일관성이 있으며, 덜 인기있는 플랫폼의 채택으로 인해 개발 프로세스를 변경할 필요가 없습니다. 성능 : 플랫폼 및 지원 메커니즘은 여러 플랫폼을 지원할 때 배포 시나리오가 불충분 한 속도의 영향을받지 않도록 성능이 우수합니다. 테스트 범위 : 효율성, 규정 준수 및

맞춤형 통신 소프트웨어 개발은 의심 할 여지없이 상당한 투자입니다. 그러나 장기적으로는 이러한 프로젝트가 시장의 기성품 솔루션과 같이 생산성을 높일 수 있기 때문에 이러한 프로젝트가 더 비용 효율적 일 수 있음을 알 수 있습니다. 맞춤형 통신 시스템을 구축하는 데있어 가장 중요한 이점을 이해하십시오. 필요한 정확한 기능을 얻으십시오 구매할 수있는 상용 통신 소프트웨어에는 두 가지 잠재적 인 문제가 있습니다. 일부는 생산성을 크게 향상시킬 수있는 유용한 기능이 부족합니다. 때로는 외부 통합으로 그것들을 향상시킬 수 있지만 항상 그들을 위대하게 만드는 것은 아닙니다. 다른 소프트웨어에는 너무 많은 기능이 있으며 사용하기에는 너무 복잡합니다. 당신은 아마도 이것들 중 일부를 사용하지 않을 것입니다 (절대!). 많은 기능이 일반적으로 가격에 추가됩니다. 귀하의 필요에 따라
