Here body, I got it (I was considering the same thing, and find no codes of forking MAM channel on the Internet. Then i began my tries:-):
Run these codes below for the first time:
const Mam = require('@iota/mam')
const { asciiToTrytes, trytesToAscii } = require('@iota/converter')
const mode = 'restricted'
const channelMode = 'restricted'
const sideKey = 'VERYSECRETKEY'
const provider = 'https://nodes.devnet.iota.org'//'https://xeevee.net:14267'
const mamExplorerLink = `https://mam-explorer.firebaseapp.com/?provider=${encodeURIComponent(provider)}&mode=${mode}&key=${sideKey.padEnd(81, '9')}&root=`
// Initialise MAM State
//let mamState = Mam.init(provider)
let mamState = Mam.init(provider,'Your Seed',2)
console.log('mamState: '+ JSON.stringify(mamState))
// Set channel mode
mamState = Mam.changeMode(mamState, mode, sideKey)
console.log('after changeMode mamState: '+ JSON.stringify(mamState))
// Publish to tangle
const publish = async packet => {
// Create MAM Payload - STRING OF TRYTES
// console.log('in publish before regular')
// if (!/^[\x00-\x7F]*$/.test(JSON.stringify(packet)))
// {
// console.log('Error(errors.INVALID_ASCII_CHARS)')
// }
const trytes = asciiToTrytes(JSON.stringify(packet))
const message = await Mam.create(mamState, trytes)
//console.log('MAM object: ',JSON.stringify(message))
// Save new mamState
//console.log('old mamState: '+ JSON.stringify(mamState))
mamState = message.state
//console.log('new mamState: '+ JSON.stringify(mamState))
//console.log('root before attach is',message.root)
// Attach the payload
await Mam.attach(message.payload, message.address, 3, 9)
//console.log('Published', packet, '\n');
//console.log('after:',message.root)
return message.root
}
//console.time('test')
////timestamp: (new Date()).toLocaleString()
publish({
message: 'XXX Mainchain'
})
.then(async root => {
//Output asyncronously using "logData" callback function
await Mam.fetch(root, mode, sideKey)
// //Output syncronously once fetch is completed
const result = await Mam.fetch(root, mode, sideKey)
//console.timeEnd('test')
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
}).catch(e => {
console.log(e) })
publish({
message: 'maybe on the mainchain1'
})
.then(async root => {
const result = await Mam.fetch(root, mode, sideKey)
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
console.log('the first root is '+root)
}).catch(e => {
console.log(e)
})
publish({
message: 'maybe on the mainchain2'
}).then(async root => {
const result = await Mam.fetch(root, mode, sideKey)
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
console.log('the first root is '+root)
}).catch(e => {
console.log(e)
})
Then, run these codes for the second time(Do not change the seed):
const Mam = require('@iota/mam')
const { asciiToTrytes, trytesToAscii } = require('@iota/converter')
const mode = 'restricted'
const channelMode = 'restricted'
const sideKey = 'VERYSECRETKEY'
const provider = 'https://nodes.devnet.iota.org'//'https://xeevee.net:14267'
const mamExplorerLink = `https://mam-explorer.firebaseapp.com/?provider=${encodeURIComponent(provider)}&mode=${mode}&key=${sideKey.padEnd(81, '9')}&root=`
// Initialise MAM State
//let mamState = Mam.init(provider)
let mamState = Mam.init(provider,'Your Seed',2)
console.log('mamState: '+ JSON.stringify(mamState))
// Set channel mode
mamState = Mam.changeMode(mamState, mode, sideKey)
console.log('after changeMode mamState: '+ JSON.stringify(mamState))
// Publish to tangle
const publish = async packet => {
// Create MAM Payload - STRING OF TRYTES
// console.log('in publish before regular')
// if (!/^[\x00-\x7F]*$/.test(JSON.stringify(packet)))
// {
// console.log('Error(errors.INVALID_ASCII_CHARS)')
// }
const trytes = asciiToTrytes(JSON.stringify(packet))
const message = await Mam.create(mamState, trytes)
//console.log('MAM object: ',JSON.stringify(message))
// Save new mamState
//console.log('old mamState: '+ JSON.stringify(mamState))
mamState = message.state
//console.log('new mamState: '+ JSON.stringify(mamState))
//console.log('root before attach is',message.root)
// Attach the payload
await Mam.attach(message.payload, message.address, 3, 9)
//console.log('Published', packet, '\n');
//console.log('after:',message.root)
return message.root
}
//console.time('test')
////timestamp: (new Date()).toLocaleString()
publish({
message: 'XXX Mainchain'
})
.then(async root => {
//Output asyncronously using "logData" callback function
await Mam.fetch(root, mode, sideKey)
// //Output syncronously once fetch is completed
const result = await Mam.fetch(root, mode, sideKey)
//console.timeEnd('test')
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
}).catch(e => {
console.log(e) })
publish({
message: 'maybe on the mainchain1'
})
.then(async root => {
const result = await Mam.fetch(root, mode, sideKey)
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
console.log('the first root is '+root)
}).catch(e => {
console.log(e)
})
publish({
message: 'here we divert'
}).then(async root => {
const result = await Mam.fetch(root, mode, sideKey)
result.messages.forEach(message => console.log('Fetched and parsed', JSON.parse(trytesToAscii(message)), '\n'))
console.log('root is',root,'\n')
console.log(`Verify with MAM Explorer:\n${mamExplorerLink}${root}\n`);
console.log('the first root is '+root)
}).catch(e => {
console.log(e)
})
After all those above, we created two channels, the first is:
{XXX Mainchain} -> {maybe on the mainchain1} -> {maybe on the mainchain2}
the second is:
{XXX Mainchain} -> {maybe on the mainchain1} -> {here we divert}
And they have the same root! use the root in MAM explorer to find out what has happended(You have to query the MAM explorer for multiple times, then you will find that although the root is the same, the message chains are not!).