university.alchemy9
Your Goal: Members 你的目标:成员
Create a public constructor which takes an array of address. These addresses, plus the deployer of the function, should all be allowed to create new proposals and vote on those proposals.
创建一个公共的constructor,该函数接受一个address数组作为参数。这些地址以及该函数的部署者都应被允许创建新提案并对这些提案进行投票。
If anyone else attempts to create a proposal or vote, the call should be reverted.
如果有其他人试图创建提案或进行投票,调用应被回滚。
1 | |
Your Goal: Execute 你的目标:执行
Let’s make our minimum voting threshold be 10 participants. Once 10 members have voted yes on a proposal, execute it.
让我们将最低投票门槛设为10名参与者。一旦有10名成员对某项提案投了赞成票,就执行该提案。
Update the castVote function to execute the proposal when the 10 yes votes have been registered.
更新castVote函数,以便在登记到10张赞成票时执行该提案。
Execute the vote by sending the data to the target address using the call syntax.
使用call语法将data发送到target地址来执行投票。
1 | |
继承
child合约可以继承所有的函数和状态变量,除了private
使用override关键字,可以覆盖一些方法
现在它有一个constructor,该函数接受一个health参数。请问constructor是放在contract外面还是{里面}
在 Solidity 中,constructor(构造函数)必须放在 contract { } 内部,它是合约的 “初始化方法”,属于合约的核心成员,不能定义在合约外部(外部定义会直接编译报错)。
Your Goal: Specific Health 你的目标:特定生命值
You’ll notice that the Hero.sol file has changed on this stage! Now it has a constructor which takes a health argument.
你会注意到本阶段的Hero.sol文件发生了变化!现在它有一个constructor,该函数接受一个health参数。
Let’s modify our SuperHeroes so that Warrior has an initial health of 200 while the Mage has an initial health of 50.
让我们修改我们的超级英雄,使Warrior的初始生命值为200,而Mage的初始生命值为50。
1 | |
这是上层合约
1 | |
Your Goal: SuperHero Attacks 你的目标:超级英雄攻击
You’ll notice the Hero.sol tab has changed once again! This time there’s three important things to notice:
你会注意到Hero.sol标签又一次发生了变化!这次有三件重要的事情需要注意:
The Hero contract is an abstract contract. It has a virtual function called attack which we’ll need to override in both Warrior and Mage.
Hero合约是一个抽象合约。它有一个名为attack的virtual函数,我们需要在战士和法师中都重写这个函数。
An enum called AttackTypes has been added to the Hero contract to differentiate between the different types of attacks our heroes can do.
Hero合约中添加了一个名为AttackTypes的enum,用于区分我们的英雄可以执行的不同攻击类型。
There’s a contract called Enemy which has a method called takeAttack on it.
有一个名为Enemy的合约,它上面有一个名为takeAttack的方法。
Your job is to implement the attack function on the Warrior and Mage contracts:
你的任务是在Warrior(战士)和Mage(法师)合约上实现attack(攻击)函数:
Add an override function called attack to both the Warrior and Mage contracts. This function should take an Enemy parameter which will be an Enemy contract.
向Warrior和Mage合约中添加一个名为attack的override函数。该函数应接受一个Enemy参数,该参数将是一个Enemy合约。
Invoke takeAttack function on the Enemy contract and change the parameter based on the hero:
调用Enemy合约上的takeAttack函数,并根据英雄修改参数:
For the Warrior, invoke the enemy’s takeAttack with the Brawl attack type.
对于战士,使用Brawl攻击类型调用敌人的takeAttack。
For the Mage, invoke the enemy’s takeAttack with the Spell attack type.
对于法师,使用“法术”攻击类型调用敌人的takeAttack。
答案:
1 | |
abstract contract什么是抽象合约?
在 Solidity 中,抽象合约(abstract contract)是一种不能被直接部署的合约,它通常用于定义一些共享的功能或接口,供其他合约继承和实现。
1. 定义抽象合约:
抽象合约本质上是包含未实现的函数的合约。一个抽象合约可以包含已实现的函数,也可以包含未实现的函数。抽象合约无法直接部署在区块链上,因为它缺少某些实现,通常需要通过继承的方式被子合约继承并完成未实现的部分。
2. 为什么需要抽象合约:
- 代码重用:抽象合约可以定义一些通用的功能或接口,子合约可以继承这些功能并实现自己的业务逻辑。
- 接口定义:可以将一些公共函数声明为抽象函数,要求继承者提供具体实现,类似于接口(interface)。
- 限制性设计:通过抽象合约,可以强制要求继承者实现某些方法,确保子合约的行为一致性。
3. 抽象合约的语法:
在 Solidity 中,abstract 关键字用于声明抽象合约。例如:
1 | |
4. 抽象合约的关键点:
抽象函数:在抽象合约中,函数可以被声明为
virtual且没有实现(没有函数体),这类函数被称为“抽象函数”。继承这个抽象合约的子合约必须提供对这些函数的具体实现。1
function vote(uint proposalId, bool support) external virtual;已实现的函数:抽象合约中也可以包含已实现的函数,子合约可以直接继承这些已实现的功能,无需重写。
1
2
3function getVoteCount(uint proposalId) public view returns (uint) {
return 0; // 示例返回值
}无法直接部署:抽象合约不能被直接部署到区块链上,因为它包含了未实现的抽象函数。只有继承了这个抽象合约并实现了所有抽象函数的合约才能被部署。
5. 如何使用抽象合约:
示例:
1 | |
解释:
AbstractVoting合约:- 定义了一个抽象函数
vote(uint proposalId, bool support),子合约必须实现这个函数。 - 定义了一个已实现的函数
getProposalCount(),返回一个示例值。这个函数在继承的合约中可以直接使用,无需重写。
- 定义了一个抽象函数
Voting合约:- 继承了
AbstractVoting抽象合约。 - 实现了抽象函数
vote(uint proposalId, bool support),这是强制要求的,因为AbstractVoting中的vote函数是抽象的,没有实现。 - 使用
override关键字来表示重写了父合约中的抽象函数。
- 继承了
6. 抽象合约 vs. 接口:
抽象合约和接口有一些相似之处,但它们之间有几个关键区别:
- 抽象合约:可以包含已实现的函数和抽象函数,子合约可以继承并重写这些函数。
- 接口(Interface):只能包含未实现的函数,没有状态变量和已实现的函数,所有函数都必须是抽象的。子合约必须实现接口中声明的所有函数。
7. 总结:
- 抽象合约是一个不能直接部署的合约,它用于提供基础功能和接口,供其他合约继承和实现。
- 它包含抽象函数(没有实现),以及可以实现的函数。
- 子合约必须实现抽象合约中声明的所有抽象函数。
super.modify是什么意思?
在 Solidity 中,super.modify() 是用于调用父合约(即 Base 合约)中已实现的方法。它允许在子合约中调用父合约的函数,尤其是在函数被重写(override)的情况下。
解释 super.modify() 的含义:
在你提供的代码中,Derived 合约重写了 Base 合约中的 modify 函数,并在其内部调用了 super.modify()。
代码分析:
1 | |
super.modify() 的作用:
super是 Solidity 中的一个关键字,用于引用父合约的函数。它允许你调用父合约中被子合约重写的函数。- 在
Derived合约中,super.modify()调用的是Base合约中的modify()函数,而不是Derived合约中的modify()函数。
具体步骤:
Derived合约中的modify():value += 20;:首先,value被增加了 20,value从 10 变为 30。- 然后,调用
super.modify()。
super.modify():- 这会调用父合约
Base中的modify()函数。 - 在
Base合约中,modify()函数是将value乘以 2。所以,此时value将从 30 变为 60。
- 这会调用父合约
总结:
super.modify()使得Derived合约在执行完自己定义的modify()函数后,能够调用父合约Base中的modify()函数,从而实现修改value的值。
举个例子,详细说明:
初始化:
Base合约中的value初始值为 10。调用
Derived合约的modify()函数:value += 20;将value的值增加 20,变成 30。- 然后,
super.modify()调用父合约的modify(),即Base.modify(),这会将value乘以 2,变成 60。
因此,在 Derived 合约中的 modify() 执行完后,value 的最终值是 60。
总结:
super.modify()调用父合约中的modify()函数。- 你可以通过
super来调用父合约的函数,尤其在子合约中重写父合约的函数时,它非常有用,可以确保在子合约中执行父合约的功能。
Your Goal: Add the Super! 你的目标:添加Super!
The attack function is now implemented by the Hero base contract. It will take the enemy as an argument and decrement energy from our hero after every attack.
attack函数现在由Hero基合约实现。它将接收enemy作为参数,并在每次攻击后减少我们英雄的energy。
Let’s invoke this base contract function from within the attack function for both (derived) hero contracts: Mage and Warrior.
让我们从两个(派生的)英雄合约(法师和战士)的attack函数中调用这个基础合约函数。
1 | |
Your goal is to fill out the Ownable base contract, which will be used by the Collectible contract!
你的目标是填写Ownable基础合约,它将被Collectible合约使用!
The owner should be defined in the Ownable base contract
owner 应在 Ownable 基础合约中定义
Ensure that markPrice can only be called by the owner (the deployer of the collectible)
确保只有owner(收藏品的部署者)可以调用markPrice
1 | |
Your Goal: Collectible Transferable 你的目标:可收集的 可转移的
The Collectible contract now also inherits from Transferable, a contract which has not been created yet!
现在,Collectible合约还继承自Transferable合约,而后者尚未创建!
Your goal is to create a new contract Transferable that will allow the Collectible to transfer its ownership to another address.
你的目标是创建一个新的合约Transferable,它将允许Collectible将其所有权转移到另一个地址。
In the Transferable contract, create a function called transfer which takes an address for the new owner.
在Transferable合约中,创建一个名为transfer的函数,该函数接收新所有者的address作为参数。
Have this function transfer ownership from the current owner to the new owner passed in.
让此函数将所有权从当前所有者转移到传入的新所有者。
Ensure that this function can only be called by the current owner.
确保此函数只能由当前所有者调用。
1 | |

课程完结