【Classic TDD by Example】C# 版無限期、不限次 影音培訓內容正式推出,開放報名。
完成介紹,請參考:https://tdd.best/courses/classic-tdd-by-example-video-training/
【#你可以學會什麼】
➀ 怎麼做需求分析、測試案例分析、backlog items 分析、TDD 的測試案例設計、單元測試、TDD 的小步快跑、持續重構、假實作加上三角定位法。
➁ code smell 的辨識,例如 duplication, temp variable, primitive obsession, feature envy 等等。
➂ 會用到的重構功能與技能,大概整個 IDE 的重構功能都涵蓋到了,包含:
- rename, introduce variable/parameter/field
- extract method/class/interface/super class
- inline variable/field/parameter/method
- move/make method non-static (move class, folder, namespace)
- push member down
- replace switch/nested if logic
- split/merge/join variable
- change signature
- 如何移掉 out 參數的設計
➃ 設計原則:SOLID, 關注點分離, Simple Design
➄ 實戰 Refactoring to Patterns: strategy, chain of responsibility, template method…
【#你會得到的服務與內容】
➀ 你會拿到兩個影片,包含需求面的說明、解析、測試案例分析設計、待辦清單的設計。長度加起來為12小時40分鐘。
➁ 有一份線上講義,匯出成 PDF 共計 159 頁。(作業為2頁)
➂ 有一份 mind map, 跟著培訓做,會有 338 個 elements/nodes。
➃ GitHub上一份 181個 commits 的參考。
➄ 會有一個 slack workspace 供大家在上面發問、討論交流,以及方便我補充相關內容。
➅ 額外提供1hr online 1-1 coaching,企業報價為10630(不信的,有好幾張不同時間的發票金額與天數備註為證明,歡迎來跟我打賭)
➆ 如果因為這門培訓的練習,讓你打算訂閱 JetBrains IDE, 可獲得個人首年訂閱8折的 coupon, 舉例來說,如果是只有 Rider, 就可省27.8美元,如果是全家餐(全系列 10個 IDE 產品),則是節省 99.8 美元。
【#適合哪些朋友】
➀ 因為時空因素(例如人在國外或外地、因為疫情、因為週末時間得陪伴家人,只有深夜才能擁有自己時間的朋友),無法參加我的培訓,但又很想突破自己能力瓶頸的朋友,至少我很肯定你可以從中先獲得工作上有幫助的內容。
➁ 不想等那麼久才能上到實體課,怎麼報名都只能排在等待清單,要等到啥時才可以變強啊啊啊啊啊… 的朋友。畢竟我 2021 年的所有課,在一月份就已經全數額滿了。
➂ 喜歡反覆觀看影片學習、動手練習,能從反覆複習的過程中,獲得最大學習效果,獲得不同想法刺激的學習模式的朋友,這一次的影片絕對可以滿足你的學習方式。
➃ 上我的實體課覺得時間太短、觀念太多、實作跟不上,身心靈在實務課程節奏有點緊湊感覺吃力的朋友,但又覺得內容充實,可以學到很多東西的朋友,這是最適合你做一次打好基底的內容與形式。
➄ 對於內容提及的部份,覺得觀念不夠清楚,不知道怎麼實際進行重構、設計與實作出那些技巧和模式,最終達成 #簡單設計 成果的朋友。
甚至我覺得,即使不是這種學習模式的朋友,大概也避不掉得反覆看、反覆練習好幾遍,因為要行雲流水,得各環節都打通才行。
【#不適合哪些朋友】
➀ 如果因為影片課程的屬性,而只期待著課程費用要比較低的朋友,建議不要買。
➁ 只想看影片,不想打開 IDE 跟著練習 coding 的,建議不要買。不要浪費時間浪費錢,你只看食譜也無法學會煮菜,只看游泳的影片也無法學會游泳的。
➂ 看不懂也不想發問的人,不要買。因為這樣誰都幫不了你。
➃ 不想要自己相關資料被壓浮水印在自己購買的影片上的人,不要買。有壓你個資的影片,只有你跟我擁有。而你的個資只會在影片上使用,不會挪作他用。(確定的是,上面不會有身份證字號或護照號碼)
【#票價資訊】
♥ 一般票:NT$ 36,000
♥ 過來人推薦票(請附上已經購買此影音課程的推薦人,報名附上他的出貨序號,以及 email):NT$ 35,000
♥ 老鳥票(指 2018 年後參加過 91 的公開培訓課): NT$ 34,500
定價標準緣由,請見課程介紹。
【#報名方式】
想要報名的同學,請將下列的報名資訊 joeychen@odd-e.com。確認報名成功之後,我會回信給您告知出貨序號,以及對應的匯款資訊。
> 信件標題:Classic TDD by Example: {name} 報名 {程式語言版本}
- 真實姓名
- 聯絡電話
- email (相關權限與未來老鳥票依據)
- 遮罩過的身份證照片(身份證字號、生日、換發日請都遮罩)
- 與真實姓名能對得起來的名片、帳單或信件照片(用來雙重驗證真實姓名的一致性,以免有人用他人身份證或網路上的身份證照片)
- 程式語言
- 推薦人的出貨序號與 email (如果票種選擇 【過來人推薦票】,請附上此資訊)
【#授權條款】
購買人付費之後,等同於已同意下列條款:
- 授權僅限本人觀看,不限制裝置,無限期,無限次觀看影片。不依賴於平台,將直接提供影片下載連結,所以請不用擔心在平台上下架的問題。
- 購買將採實名驗證,影片將壓上購買人相關個人資訊浮水印。影片、程式碼內容等,未經本人授權,不得於公開場所、平台觀看,不得擅自販售、分享、散佈、擷取圖片或影片片段侵害作者權益等行為。請購買人妥善保管影片,以保護雙方權益。
- 不論「有償或無償」,均不得已在未經同意的情況下將影片做公開分享、重製、散佈、改做
- 本於誠實信用原則,影片僅供個人學習使用,不得共用
- 若違反前述約定,則著作財產權人可以請求所受損害與所失利益
【#出貨清單與出貨狀態】
因每個人的影片都會有客製化的調整與浮水印資訊,故每天產能有限,目前一天可處理 4~8 張訂單。
所以列出對應的出貨清單與狀態,各位可以看到自己的出貨序號,以及目前處理到哪一張訂單了。
出貨清單:https://hackmd.io/@SYvyb1O4SLq8W6nvAQW5mw/ByVVUt86O
同時也有10000部Youtube影片,追蹤數超過2,910的網紅コバにゃんチャンネル,也在其Youtube影片中提到,...
c# interface example 在 Taipei Ethereum Meetup Facebook 的最佳貼文
📜 [專欄新文章] Reason Why You Should Use EIP1167 Proxy Contract. (With Tutorial)
✍️ Ping Chen
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
EIP1167 minimal proxy contract is a standardized, gas-efficient way to deploy a bunch of contract clones from a factory.
1. Who may consider using EIP1167
For some DApp that are creating clones of a contract for its users, a “factory pattern” is usually introduced. Users simply interact with the factory to get a copy. For example, Gnosis Multisig Wallet has a factory. So, instead of copy-and-paste the source code to Remix, compile, key in some parameters, and deploy it by yourself, you can just ask the factory to create a wallet for you since the contract code has already been on-chain.
The problem is: we need standalone contract instances for each user, but then we’ll have many copies of the same bytecode on the blockchain, which seems redundant. Take multisig wallet as an example, different multisig wallet instances have separate addresses to receive assets and store the wallet’s owners’ addresses, but they can share the same program logic by referring to the same library. We call them ‘proxy contracts’.
One of the most famous proxy contract users is Uniswap. It also has a factory pattern to create exchanges for each ERC20 tokens. Different from Gnosis Multisig, Uniswap only has one exchange instance that contains full bytecode as the program logic, and the remainders are all proxies. So, when you go to Etherscan to check out the code, you’ll see a short bytecode, which is unlikely an implementation of an exchange.
0x3660006000376110006000366000732157a7894439191e520825fe9399ab8655e0f7085af41558576110006000f3
What it does is blindly relay every incoming transaction to the reference contract 0x2157a7894439191e520825fe9399ab8655e0f708by delegatecall.
Every proxy is a 100% replica of that contract but serving for different tokens.
The length of the creation code of Uniswap exchange implementation is 12468 bytes. A proxy contract, however, has only 46 bytes, which is much more gas efficient. So, if your DApp is in a scenario of creating copies of a contract, no matter for each user, each token, or what else, you may consider using proxy contracts to save gas.
2. Why use EIP1167
According to the proposal, EIP is a “minimal proxy contract”. It is currently the known shortest(in bytecode) and lowest gas consumption overhead implementation of proxy contract. Though most ERCs are protocols or interfaces, EIP1167 is the “best practice” of a proxy contract. It uses some EVM black magic to optimize performance.
EIP1167 not only minimizes length, but it is also literally a “minimal” proxy that does nothing but proxying. It minimizes trust. Unlike other upgradable proxy contracts that rely on the honesty of their administrator (who can change the implementation), address in EIP1167 is hardcoded in bytecode and remain unchangeable.
That brings convenience to the community.
Etherscan automatically displays code for EIP1167 proxies.
When you see an EIP1167 proxy, you can definitely regard it as the contract that it points to. For instance, if Etherscan finds a contract meets the format of EIP1167, and the reference implementation’s code has been published, it will automatically use that code for the proxy contract. Unfortunately, non-standard EIP1167 proxies like Uniswap will not benefit from this kind of network effect.
3. How to upgrade a contract to EIP1167 compatible
*Please read all the steps before use, otherwise there might have problems.
A. Build a clone factory
For Vyper, there’s a function create_with_code_of(address)that creates a proxy and returns its address. For Solidity, you may find a reference implementation here.
function createClone(address target) internal returns (address result){ bytes20 targetBytes = bytes20(target); assembly { let clone := mload(0x40) mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(clone, 0x14), targetBytes) mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) result := create(0, clone, 0x37) }}
You can either deploy the implementation contract first or deploy it with the factory’s constructor. I’ll suggest the former, so you can optimize it with higher runs.
contract WalletFactory is CloneFactory { address Template = "0xc0ffee"; function createWallet() external returns (address newWallet) { newWallet = createClone(Template); }}
B. Replace constructor with initializer
When it comes to a contract, there are two kinds of code: creation code and runtime code. Runtime code is the actual business logic stored in the contract’s code slot. Creation code, on the other hand, is runtime code plus an initialization process. When you compile a solidity source code, the output bytecode you get is creation code. And the permanent bytecode you can find on the blockchain is runtime code.
For EIP1167 proxies, we say it ‘clones’ a contract. It actually clones a contract’s runtime code. But if the contract that it is cloning has a constructor, the clone is not 100% precise. So, we need to slightly modify our implementation contract. Replace the constructor with an ‘initializer’, which is part of the permanent code but can only be called once.
// constructorconstructor(address _owner) external { owner = _owner;}// initializerfunction set(address _owner) external { require(owner == address(0)); owner = _owner;}
Mind that initializer is not a constructor, so theoretically it can be called multiple times. You need to maintain the edge case by yourself. Take the code above as an example, when the contract is initialized, the owner must never be set to 0, or anyone can modify it.
C. Don’t assign value outside a function
As mentioned, a creation code contains runtime code and initialization process. A so-called “initialization process” is not only a constructor but also all the variable assignments outside a function. If an EIP1167 proxy points to a contract that assigns value outside a function, it will again have different behavior. We need to remove them.
There are two approaches to solve this problem. The first one is to turn all the variables that need to be assigned to constant. By doing so, they are no longer a variable written in the contract’s storage, but a constant value that hardcoded everywhere it is used.
bytes32 public constant symbol = "4441490000000000000000000000000000000000000000000000000000000000";uint256 public constant decimals = 18;
Second, if you really want to assign a non-constant variable while initializing, then just add it to the initializer.
mapping(address => bool) public isOwner;uint public dailyWithdrawLimit;uint public signaturesRequired;
function set(address[] _owner, uint limit, uint required) external { require(dailyWithdrawLimit == 0 && signaturesRequired == 0); dailyWithdrawLimit = limit; signaturesRequired = required; //DO SOMETHING ELSE}
Our ultimate goal is to eliminate the difference between runtime code and creation code, so EIP1167 proxy can 100% imitate its implementation.
D. Put them all together
A proxy contract pattern splits the deployment process into two. But the factory can combine two steps into one, so users won’t feel different.
contract multisigWallet { //wallet interfaces function set(address[] owners, uint required, uint limit) external;}contract walletFactory is cloneFactory { address constant template = "0xdeadbeef"; function create(address[] owners, uint required, uint limit) external returns (address) { address wallet = createClone(template); multisigWallet(wallet).set(owners, required, limit); return wallet; }}
Since both the factory and the clone/proxy has exactly the same interface, no modification is required for all the existing DApp, webpage, and tools, just enjoy the benefit of proxy contracts!
4. Drawbacks
Though proxy contract can lower the storage fee of deploying multiple clones, it will slightly increase the gas cost of each operation in the future due to the usage of delegatecall. So, if the contract is not so long(in bytes), and you expect it’ll be called millions of times, it’ll eventually be more efficient to not use EIP1167 proxies.
In addition, proxy pattern also introduces a different attack vector to the system. For EIP1167 proxies, trust is minimized since the address they point to is hardcoded in bytecode. But, if the reference contract is not permanent, some problems may happen.
You might ever hear of parity multisig wallet hack. There are multiple proxies(not EIP1167) that refer to the same implementation. However, the wallet has a self-destruct function, which empties both the storage and the code of a contract. Unfortunately, there was a bug in Parity wallet’s access control and someone accidentally gained the ownership of the original implementation. That did not directly steal assets from other parity wallets, but then the hacker deleted the original implementation, making all the remaining wallets a shell without functionality, and lock assets in it forever.
https://cointelegraph.com/news/parity-multisig-wallet-hacked-or-how-come
Conclusion
In brief, the proxy factory pattern helps you to deploy a bunch of contract clones with a considerably lower gas cost. EIP1167 defines a bytecode format standard for minimal proxy and it is supported by Etherscan.
To upgrade a contract to EIP1167 compatible, you have to remove both constructor and variable assignment outside a function. So that runtime code will contain all business logic that proxies may need.
Here’s a use case of EIP1167 proxy contract: create adapters for ERC1155 tokens to support ERC20 interface.
pelith/erc-1155-adapter
References
https://eips.ethereum.org/EIPS/eip-1167
https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7/
Donation:
pingchen.eth
0xc1F9BB72216E5ecDc97e248F65E14df1fE46600a
Reason Why You Should Use EIP1167 Proxy Contract. (With Tutorial) was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌