/ lib / modules / deploytracker / index.js
index.js
 1  let utils = require('../../utils/utils.js');
 2  let fs = require('../../core/fs.js');
 3  
 4  class DeployTracker {
 5  
 6    constructor(embark, options) {
 7      this.logger = embark.logger;
 8      this.events = embark.events;
 9      this.embark = embark;
10      this.trackContracts = (options.trackContracts !== false);
11  
12      // TODO: unclear where it comes from
13      this.env = options.env;
14      //this.chainConfig = options.chainConfig;
15      this.chainConfig = embark.config.chainTracker;
16      this.registerEvents();
17    }
18  
19    registerEvents() {
20      const self = this;
21  
22      this.embark.registerActionForEvent("deploy:beforeAll", this.setCurrentChain.bind(this));
23  
24      this.events.on("deploy:contract:deployed", (contract) => {
25        self.trackContract(contract.className, contract.realRuntimeBytecode, contract.realArgs, contract.deployedAddress);
26        self.save();
27      });
28  
29      self.embark.registerActionForEvent("deploy:contract:shouldDeploy", (params, cb) => {
30        if (!self.trackContracts) {
31          return cb(params);
32        }
33  
34        let contract = params.contract;
35        let trackedContract = self.getContract(contract.className, contract.realRuntimeBytecode, contract.realArgs);
36        if (trackedContract) {
37          params.contract.address = trackedContract.address;
38        }
39        if (params.shouldDeploy && trackedContract) {
40           params.shouldDeploy = true;
41        }
42        cb(params);
43      });
44    }
45  
46    setCurrentChain(cb) {
47      const self = this;
48      if (this.chainConfig === false) {
49        this.currentChain = {contracts: []};
50        return cb();
51      }
52      this.events.request("blockchain:block:byNumber", 0, function(_err, block) {
53        let chainId = block.hash;
54  
55        if (self.chainConfig[chainId] === undefined) {
56          self.chainConfig[chainId] = {contracts: {}};
57        }
58  
59        self.currentChain = self.chainConfig[chainId];
60  
61        self.currentChain.name = self.env;
62        cb();
63      });
64    }
65  
66    loadConfig(config) {
67      this.chainConfig = config;
68      return this;
69    }
70  
71    trackContract(contractName, code, args, address) {
72      if (!this.currentChain) return false;
73      this.currentChain.contracts[utils.sha3(code + contractName + args.join(','))] = {
74        name: contractName,
75        address: address
76      };
77    }
78  
79    getContract(contractName, code, args) {
80      if (!this.currentChain) return false;
81      let contract = this.currentChain.contracts[utils.sha3(code + contractName + args.join(','))];
82      if (contract && contract.address === undefined) {
83        return false;
84      }
85      return contract;
86    }
87  
88    // TODO: abstract this
89    // chainConfig can be an abstract PersistentObject
90    save() {
91      if (this.chainConfig === false) {
92        return;
93      }
94      fs.writeJSONSync("./chains.json", this.chainConfig, {spaces: 2});
95    }
96  
97  }
98  
99  module.exports = DeployTracker;