//tips
//基本情報理解
Open Source Softwareにおけるディストリビュータの役割は、動作に必要なライブラリやソフトウェアをパッケージングして、利用者がインストールしやすいように提供する役割を持つ。
OSSとして個々に開発されているOS、ライブラリやコマンドなどのユーティリティ、GUI、サーバソフトウェア、アプリケーションソフトウェアなどを組み合わせた実用的なパッケージを提供する。
ディストリビューションには基本的な機能が一式揃っているので、利用者はディストリビューションをインストールするだけで、複雑な環境設定等をせずに様々な機能を使えるようになる。
DRAMは1ビットの情報を記憶するためにキャパシタを利用する。キャパシタはコンデンサの一種で、単純な構造で一定時間情報を保持できるが、低速で定期的な再書き込みが必要になる。主に主記憶に使われる。
SRAMは論理回路のフリップフロップ回路で作成されており、動作は高速で、CPUのキャッシュメモリになどに使用される。
コンデンサの基本構造は、絶縁体を2個の金属板で挟み込んだ形で、電荷(電気)を蓄えることや直流電流を通さないが、交流電流は通すなどの役割を持つ。
キャパシタとは、電気を蓄えて放電できる蓄電装置でコンデンサと役割自体は同じだが、電気二重層キャパシタや、リチウムイオンキャパシタなど、大容量のものをキャパシタと呼び、従来の積層セラミックコンデンサやアルミ電解コンデンサといった小容量のものと区別する風潮にあるとのこと。
コンデンサは、電子回路や電源回路等でよく使われる電気を蓄えたり放出したりする小型の電子部品のことを指す場合が多く、特に電子回路で使われる。
フリップフロップ回路とは、最も基本的な構造の論理回路の一つで、二つの状態、「0」および「1」のいずれかを保持することができるもの。 現在の入力と共に過去の入力も利用する順序回路の一種で、SRAMやマイクロプロセッサ(CPU/MPU)内部のレジスタ、キャッシュメモリなどに応用されている。
//Pitch deck
今日はナイジェリアのPodoziという女性用beauty e-commerce platformのpitchを確認。10枚のスライドでとてもシンプル。
インサイトとしては、アフリカ女性の年間収益の25%がbeautyへの出費がとなっており、一般的な米国女性の出費の約5倍。だが、それにもかかわらず彼女らのスキンカラーにあったbeauty商品が少ないなどの問題があり、それを解決するプラットフォームを作っている。話を聞いていると成長しそうに思える。
YouTubeの実際のプレゼンを聞いた方がなるほどと思えたので下記にyoutubeの方を掲載する。
//smart contract
今度はGreeterコントラクトから返される値を動的に指定できるようにしていく。
これはgreet関数から返されるメッセージを設定する関数で補えば良い。
Test/greeter-test.jsファイルに別のcontractブロックを作成する。
スクリプトに下記を追加。contractを追加。
contract("Greeter:update greeting",()=>{
describe("SetGreeting(string)",()=>{
it("sets greeting to passed in string",async()=>{
const greeter = await GreeterContract.deployed();
const expected="Hi,there!";
await greeter.setGreeting(expected);
const actual=await greeter.greet();
assert.equal(actual,expected,"greeting was not updated")
});
});
});
Jsの方で追加ができたら、今度はGreeter.solの方に追加。
pragma solidity >= 0.4.0 < 0.7.0;
contract Greeter{
string private _greeting;
function greet() external pure returns(string memory){
return "Hello,World!";
}
function setGreeting(string calldata greeting) external {
}
}
ここからpureからviewに変換する必要があることなどは理解できていないが、.solが今までc#で書いていたようなコード記載に近く、それをjs側がうまく改変してチェーン側に繋いでくれているということがぼんやりわかってきた。
pragma solidity >= 0.4.0 < 0.7.0;
contract Greeter{
string private _greeting="Hello,World!";
function greet() external view returns(string memory){
return _greeting;
}
function setGreeting(string calldata greeting) external {
_greeting=greeting;
}
}
こうするとtruffle testで下記のように更新し、テストを成功させることができた。
Contract: Greeter
✓ has been deployed successfully
greet()
✓ returns 'Hello,World!'
Contract: Greeter:update greeting
SetGreeting(string)
✓ sets greeting to passed in string (63ms)
この時点では誰もがGreeterコントラクトのメッセージを変更できるので、コントラクトに所有権の概念を追加し、挨拶文を変更できる人を限定する。これをownerableにするというよう。
greeter_test.jsのcontract("Greeter”,()部分に下記を追加。状態の変化を前提としていないのでcontract("Greeter:update greeting”,()に追加するのではない。
describe("owner()",()=>{
it("returns the address of the owner",async()=>{
const greeter = await GreeterContract.deployed();
const owner=await greeter.owner();
assert(owner,"the current owner");
});
});
このowner関数を実行するために.solに追加を行う。
pragma solidity >= 0.4.0 < 0.7.0;
contract Greeter{
string private _greeting="Hello,World!";
address private _owner;
function greet() external view returns(string memory){
return _greeting;
}
function setGreeting(string calldata greeting) external {
_greeting=greeting;
}
function owner() public view returns(address){
return _owner;
}
}
所有者のアドレスがデプロイ元のアドレスと同じことをチェックする必要があるのでaccounts関数を使用してアカウント情報との照合を行う必要がある。
なのでjsの方のowner()に関する部分を下記のように拡張。
describe("owner()",()=>{
it("returns the address of the owner",async()=>{
const greeter = await GreeterContract.deployed();
const owner=await greeter.owner();
assert(owner,"the current owner");
});
it("matches the address that originally deployed the contract",async()=>{
const greeter = await GreeterContract.deployed();
const owner=await greeter.owner();
const expected=accounts[0];
assert.equal(owner,expected,"matches address used to deploy contract");
});
});
ここからコントラクト初期化時にmsg.senderを所有者として記録する。これで作成者をわかるようにした。
.solに下記を追加。
address private _owner;
constructor()public{
_owner=msg.sender;
}
さらに所有者以外がメッセージを送信するケースにも対策。
contract("Greeter:update greeting",(accounts)=>{
describe("SetGreeting(string)",()=>{
describe("when message is sent by the owner)",()=>{
it("sets greeting to passed in string",async()=>{
const greeter = await GreeterContract.deployed();
const expected="The owner changed the message";
await greeter.setGreeting(expected);
const actual=await greeter.greet();
assert.equal(actual,expected,"greeting updated")
});
});
describe("when message is sent by another account)",()=>{
it("does not set the greeting",async()=>{
const greeter = await GreeterContract.deployed();
const expected=await greeter.greet();
try{
await greeter.setGreeting("Not the owner",{from :accounts[1]});
}catch(err)
{
const errorMessage="Ownable:caller is not the owner";
assert.equal(err.reason,errorMessage,"greeting should not update");
return;
}
assert(false,"greeting should not update");
});
});
});
});
.solの方も追加で修正する。
modifier onlyOwner(){
require(
msg.sender==_owner,
"Ownable:caller is not the owner"
);
_;
}
_;は修飾されている関数が呼び出される場所でこの行の後に追加したものは関数本体の実行が完了した後に実行されるとのこと。
これで一通りの設定ができたので最後にnpm install openzeppelin-solidityを実行し、
pragma solidity >= 0.4.0 < 0.7.0;
import"openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract Greeter is Ownable{
string private _greeting="Hello,World!";
function greet() external view returns(string memory){
return _greeting;
}
function setGreeting(string calldata greeting) external onlyOwner{
_greeting=greeting;
}
function owner() public view returns(address){
return _owner;
}
modifier onlyOwner(){
require(
msg.sender==_owner,
"Ownable:caller is not the owner"
);
_;
}
}
これにてgreeterコントラクトの開発が完了。jsとsolidityの構文は別途復習が必要。